|
Prev: Special container
Next: map within map
From: Carlos Moreno on 12 Aug 2005 21:33 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 13 Aug 2005 09:13 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 13 Aug 2005 09:12 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 13 Aug 2005 09:17 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 13 Aug 2005 09:15
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! ] |