From: Carlos Moreno on
Jeff Schwab wrote:

>>>>>if( some_pointer != 0 ) // if( some_pointer )
>>>>
>>>>What's wrong with this? It is clearer than your version, which looks
>>>>like a boolean test. I mean, you are not *really* asking if
>>>>some_pointer is true...
>>>
>>>Conditions in C++ don't test for truth, they test for non-zero.
>>
>>This is very *very* wrong (as I'm sure the 20 replies before mine
>>would clarify :-))
>
> Oh, very, *very* wrong. I'm sure none of my loops or if-statements work
> properly.

If you do not understand that this is entirely irrelevant, then there
is no point in continuing the discussion.

The reason why your loops work *is not* that conditions test for
non-zero (if testing for non-zero was a condition for loops to work,
then no, some your loops would not work -- more like would not even
compile, I guess). The reason why your loops compile and work is
because whatever you put as the condition is either a boolean, or
something implicitly convertible to boolean.

The above is so obvious that I'm almost embarrased to have to even
say it. But it seems necessary when you still argue in defense of
an incorrect statement (with an incorrect argument, of course).

The original complaint of using if (some_pointer) makes a lot of
sense to me -- when you declare, in C, an int variable that you
intend it to pass as a boolean, then fine; you give it a name that
suggests true/false (such as "done", or "element_found", etc.), and
you just use it as if it were a boolean -- the fact that in C,
conditions test for non-zero works out nicely, because the syntax
resembles that of a true boolean (no pun intended). But making a
pointer pass as a boolean is, in a sense, deceptive (ok, deceptive
is too strong a word, but it's the only one I can think of whose
meaning reflects what I'm trying to say). It *does* work, of
course, because there is an explicit rule for implicit conversion
from pointer to boolean; but the fact that it works doesn't mean
that it is nice or that it is convenient (IMHO, it's neither).

>>Conditions *in C++* test for truth -- period. Any expression that
>>evaluates to boolean or to something implicitly convertible to
>>boolean (such as a pointer, or a numeric value) can be used as a
>>condition.
>
> After you say "period," you probably shouldn't have to explain that
> there's really a lot more to the story.

There isn't more to the story. The statements after the "period"
go to explain why something that apparently contradicts the previous
statement, does not really contradict it. It does not change the
fact that conditions in C++ test for truth [period].

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
ThosRTanner wrote:
> 4) All the bits of defined undefined behaviour in the standard (and
> those people who feel that because experts understand all these
> nuances, there's no need to change the language).
> Current favourites are:
> a) The fun you get when inheriting from a class with a non-virtual
> destructor

Hehe, I just stumbled across one like that, and examining the case was
interesting:

class socket{
/** nonvirtual! */
~socket() {
close();
}
/** yes, using strings to convey errors messages */
virtual std::string close();
};

This was followed by a few other classes derived from this one, neither of
which had any non-POD members. Once I understood the true nature of this,
I quickly removed the 'virtual' I had immediately put on the dtor and
rather put a big remark that this needs serious fixing.

For those that didn't get the insidiousness, here's the explanation:

I. A virtual dtor makes a delete on a pointer to the baseclass call the
most derived class' dtor. Invoking the baseclass' dtor directly (which is
the case here) leads to undefined behaviour (by the standard) and in
practice to 1) not executing the derived class' dtor code and not calling
the dtor of the derived class' members. In short, it leads to leaks of
memory or other resources.
II. In the baseclass' dtor (and ctor, but that just btw) the object has
both the static and dynamic type 'baseclass', regardless of whether it is
called in the path of creating a derived class' object. This is
particularly important because a call to a virtual function (like
close()!) would call the baseclass' version, even if the derived class
overrides it.
In particular this call to the virtual close() from the dtor is tempting,
but it doesn't work - each derived class needs to care for its own things
in the dtor.
III. Now why did I not add a 'virtual' to the dtor? The point is that, the
rule that in the baseclass' dtor the object has the dynamic type
'baseclass' has been broken, because invoking delete on the pointer to
baseclass does not first call the derived class' dtor as the dtor is not
virtual. Now, the dynamic type of the object in the dtor is in fact
'derived class', so the call to close() does exactly what the author
wants.

Since the derived classes only have POD members and any associated
resources are released in close(), this atrocity in fact does its job
without leaking resources or memory.
Needless to say that this depends on the implementation and is completely
fubar anyway, so don't try to do this at home, kids!

> 6) People who insist that while(1) {...} is more efficient than for(;;)
> {..}

Sorry, but the Right Form(tm) is 'while(true) { ... }'

Uli

--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Valery Aronov on
The last one (... 7) Classes which consist of entirely public static
functions ...) has got a legitimate place in the metaprogramming to
define some recursive functions.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
Maciej Sobczak wrote:
> (Occam's Razor comes to mind):
>
> while (*b != v && b != e)
> ++b;

That's a sharp tool you talk about and you just cut yourself. Please turn
the two sides of the && around and hope that it's not overloaded to make
this right.

;)

Uli

--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Dave Harris on
tony_in_da_uk(a)yahoo.co.uk () wrote (abridged):
> I'm wondering what other C++ programmer's pet peeves are.

Code layout, especially:

if (condition) statement;

while (condition) statement;

rather than:

if (condition)
statement;

while (condition)
statement;

-- Dave Harris, Nottingham, UK.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Prev: Special container
Next: map within map