- Bug in the C++ 2011 specifications - 19 Updates
- Backporting std::move code - 2 Updates
- St. Paul, Minnesota - 1 Update
Melzzzzz <mel@zzzzz.com>: Aug 15 02:07AM +0200 On Sun, 14 Aug 2016 23:08:05 +0200 > That is a condensate of a problem that will appear in a huge program > where conceptually those 12 lines are dispersed in several different > files across several classes and templates and what have you!!!!! That program is broken, then. Heaving non explicit conversion constructor is bug waiting to happen. Actually, except conversion from char* to std::string I never saw any other in C++ programs... |
Melzzzzz <mel@zzzzz.com>: Aug 15 02:12AM +0200 On Sun, 14 Aug 2016 23:17:40 +0200 > generation are unified in a standard context and added to some users > and tested for years without being IMPOSED to all users of the > language! C++11 makes C++ very pleasant to program in. |
Ian Collins <ian-news@hotmail.com>: Aug 15 05:20PM +1200 On 08/15/16 12:07 PM, Melzzzzz wrote: > constructor is bug waiting to happen. > Actually, except conversion from char* to std::string I never saw any > other in C++ programs... What he said! -- Ian |
Ike Naar <ike@iceland.freeshell.org>: Aug 15 06:00AM > service if you think that would be better. If you could explain what > result you were expecting and why it didn't deliver it, and how it > relates to the code you posted, that would help also. Jacob has a valid point here. If a minimal example highlights a problem, then why would it make more sense to post a huge pile of "real" code instead of the minimal example? And why would a huge pile of code be more "real" than a minimal example? What exactly is "unreal" about the minimal example? You're calling Jacob. Why not doing the work yourself, and extend/embellish the given minimal example to make it "real", and post the result here? And, if you wish, please point out which embellishments make the extended example more appropriate to illustrate the underlying problem than the minimal example would. |
Bo Persson <bop@gmb.dk>: Aug 15 08:58AM +0200 On 2016-08-15 08:00, Ike Naar wrote: > "real" code instead of the minimal example? > And why would a huge pile of code be more "real" than a minimal example? > What exactly is "unreal" about the minimal example? Because the example contains code you would never write in the first place. Everyone knows that if you have both a converting constructor and a conversion operator in the same code, the code is broken. If you try Jacob's favorite language C, it too has problems #define min(a, b) a < b ? a : b x = min(x++, y++) This also gives unexpected results. Is C also broken? Bo Persson |
Ike Naar <ike@iceland.freeshell.org>: Aug 15 07:14AM > Because the example contains code you would never write in the first > place. Everyone knows that if you have both a converting constructor and > a conversion operator in the same code, the code is broken. That doesn't explain why a "real" would illustrate this better than the minimal example. If the minimal example is broken, the "real" example will also be broken, but you'd have to spend far more energy to find this out, because of the sheer size of the "real" example. |
Ian Collins <ian-news@hotmail.com>: Aug 15 08:54PM +1200 On 08/15/16 07:14 PM, Ike Naar wrote: > the minimal example. If the minimal example is broken, the "real" > example will also be broken, but you'd have to spend far more energy > to find this out, because of the sheer size of the "real" example. Probably because the "problem" is something that wouldn't show up in real code. It's easy to find contrived examples, it's much harder finding coding standards that would allow them! -- Ian |
David Brown <david.brown@hesbynett.no>: Aug 15 11:18AM +0200 On 15/08/16 10:54, Ian Collins wrote: > Probably because the "problem" is something that wouldn't show up in > real code. It's easy to find contrived examples, it's much harder > finding coding standards that would allow them! Unfortunately, many programmers don't use coding standards as such, or formal code reviews, or good test procedures. People /do/ write code that allows implicit conversions that they had not expected, or did not intend, especially pre C++11. Getting it all right can be difficult (again, especially pre C++11) - look at the "safe bool idiom". Of course this does not mean that C++ is "broken" - it just illustrates one of the possible dangers or sources of confusion in the language. Like many features, implicit conversions can be used to write clear, concise, safe and efficient code - but they can also lead to mistakes. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 15 01:37PM +0100 On Mon, 15 Aug 2016 11:18:25 +0200 > On 15/08/16 10:54, Ian Collins wrote: > > On 08/15/16 07:14 PM, Ike Naar wrote: [snip] > the language. Like many features, implicit conversions can be used to > write clear, concise, safe and efficient code - but they can also > lead to mistakes. The undesirability of providing conversion constructors without a lot of careful prior thought is, I think, well recognised these days. However, although the issue in the original posting did indeed involve an implicit conversion from int to X as one part of its mode of operation, the "bug" referred to also involved the interaction of this with function overloading and compile time constants, of a bizarre kind. It involved passing an integer member of a zero initialized temporary of an aggregate type S ('S().n'), and it was alleged that in C++11/14, the test case should print "Pointer!" because in C++11/14 the expression comprises a constant expression of value 0, which would be a match for the function overload taking void* by virtue of it also being a null pointer constant. This is entirely contrived, and it is pretty much inconceivable that this situation would arise in real code, even with a developer taking a punt with implicit conversions. No one in their right minds is going to pass an integer member of a temporary zero-initialized aggregate literal type to another function using the dot operator because it is completely without purpose. As it happens none of the compilers I have tested this with (g++ going from version 4.4 to 6.1 and clang++ 3.8.1) actually behave like this. They all print "X!" whether compiled with -std=c++98 or -std=c++{0x,11,14}. I can't even get this to misbehave, using either g++ or clang++: constexpr int zero = 0; f(zero); It looks as if constexpr integers of value 0 are not in fact null pointer constants in C++11/14. Chris |
David Brown <david.brown@hesbynett.no>: Aug 15 02:55PM +0200 On 15/08/16 14:37, Chris Vine wrote: > It looks as if constexpr integers of value 0 are not in fact null > pointer constants in C++11/14. > Chris I agree that this exact example is contrived, and I also failed to trigger the inconsistent behaviour that has been claimed for it. But I think the more general point of programmers sometimes getting unexpected behaviour from implicit conversions stands. Conversions involving 0 can be particularly confusing because they may end up as pointers, or as integers, depending on the circumstances of the code. (The rules of C++ for this sort of thing are, I believe, unambiguous - but they are not always simple.) All I am really saying here is that this kind of thing can be quite complicated, and if due care is not taken (and due care is not always taken when programming), then accidents can happen in /real/ code. Some of the new features of C++11, such as nullptr and explicit conversion operators, address this and make it easier to write code the does what you want (while avoiding writing code that also does things you don't want!). This means that if you are using C++11 onwards, you must take care to use these new features appropriately - and if you are using C++03 or earlier, you must be even more careful. (I don't mean this is a problem with C++ - it is simply one of the costs of the powerful language.) |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 15 02:21PM +0100 On Mon, 15 Aug 2016 14:55:59 +0200 David Brown <david.brown@hesbynett.no> wrote: [snip] > and if you are using C++03 or earlier, you must be even more careful. > (I don't mean this is a problem with C++ - it is simply one of the > costs of the powerful language.) I think we can happily agree on this. Anyway, I have found the answer to the original point. In §4.10/1 of C++11 as originally published a null pointer constant was defined as follows: "A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t." DR903 (also incorporated in C++14) corrected this to read: "A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t." So the correct behaviour in C++14 or with DR903 is to print "X!". My example: constexpr int zero = 0; f(zero); was bogus even under original C++11 because zero is not a prvalue. Interestingly I have found a gcc bug. This: f(int{}); prints "X!" because int{} is not an integer literal, and it does do so with gcc and lang-3.8.1. However this prints "Pointer!" with gcc-4.6.1 but not clang: f(int()); which seems to me to be wrong. Chris |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 15 02:50PM +0100 On Mon, 15 Aug 2016 14:21:28 +0100 Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote: [snip] However this prints "Pointer!" with > gcc-4.6.1 but not clang: > f(int()); > which seems to me to be wrong. Ah, it is a gcc bug but appears to be a deliberate one to maintain compatibility with C++98. If you want the more bullet-proof C++14 conforming behaviour with gcc then it appears you have to use the 'f(int{})' form. Chris |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 15 06:35PM +0200 On 15.08.2016 15:50, Chris Vine wrote: > compatibility with C++98. If you want the more bullet-proof C++14 > conforming behaviour with gcc then it appears you have to use the > 'f(int{})' form. Good work, that clears up a lot of things for me. So, it's C++14 that changed the requirement from constant expression to literal. 3rd revision of beliefs... :-) Cheers, - Alf |
"Öö Tiib" <ootiib@hot.ee>: Aug 15 09:55AM -0700 On Sunday, 14 August 2016 02:37:04 UTC+3, jacob navia wrote: > https://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Clang-Defending-C-from-Murphy-s-Million-Monkeys > In that talk, see the slide and discussion. Starts around minute 47 of > the video Note that it is speech from February 2012. I can't find compilers that print X! at 2016. Whatever caused his opinion that the (unusual) code in your original post must print "Pointer!" must be is now gone. However I agree with you that initialization of C++11 was screwed up. Anyone who makes implicit conversion constructors, conversion operators, constructor templates, constructors that accept 'std::initializer_list' and/or something that is multiple things from that list will likely get rather bad review from me. From bright side IMHO it is sole thing that C++11 broke. Rest of the features that C++11 added I like very lot. |
legalize+jeeves@mail.xmission.com (Richard): Aug 15 05:17PM [Please do not mail me a copy of your followup] jacob@jacob.remcomp.fr spake the secret code >Le 12/08/2016 à 23:43, woodbrian77@gmail.com a écrit : >> I support law abiding citizens having guns >Yes, you must live [...] *plonk* You were already very near to entering my kill file with your ranty bitching. Now that you've demonstrated no self-control, welcome to my KILL file. You and wood brain will enjoy arguing with each other while I blissfully ignore you. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
woodbrian77@gmail.com: Aug 15 10:57AM -0700 On Monday, August 15, 2016 at 11:55:57 AM UTC-5, Öö Tiib wrote: > operators, constructor templates, constructors that accept > 'std::initializer_list' and/or something that is multiple things from > that list will likely get rather bad review from me. The standard containers do some of those things. I manage to avoid most of them. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
Manfred <mx2927@gmail.com>: Aug 15 08:17PM +0200 On 08/14/2016 09:23 PM, Ian Collins wrote: > Which compilers are they? There's at least clang c++ 2011, as the initial post in this thread reported, and Chris Vine just mentioned here a similar bug in gcc 4.6.1: > gcc-4.6.1 but not clang: > f(int()); > which seems to me to be wrong. Nonetheless, I would like to make clear that in fact I just love C++. My remark was about a "risk" for C++ to get polluted along the way, not that this is actually happened so far. Regards |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 15 07:54PM +0100 On 15/08/2016 17:35, Alf P. Steinbach wrote: > So, it's C++14 that changed the requirement from constant expression to > literal. > 3rd revision of beliefs... :-) Many hours earlier I said what was being passed had a *name* which seemed to confuse you. Literals don't have names. /Flibble |
jacob navia <jacob@jacob.remcomp.fr>: Aug 15 11:40PM +0200 Le 15/08/2016 à 19:17, Richard a écrit : >>> I support law abiding citizens having guns >> Yes, you must live [...] > *plonk* The U.S.A. the only country in the civilized world where people go around with guns killing themselves. > You were already very near to entering my kill file with your ranty > bitching. I am happy that I enter your kill file without being killed by your gun. I am, and have always been, unarmed. I do not take a gun with me to kill other fellow beings. I just do not kill people. > Now that you've demonstrated no self-control, welcome to my KILL file. If you think that not killing people and not having guns is a sin... Well I can't do anything for you either. > You and wood brain will enjoy arguing with each other while I > blissfully ignore you. You are so convinced of your own importance. You and your gun. |
"Öö Tiib" <ootiib@hot.ee>: Aug 15 06:28AM -0700 On Monday, 15 August 2016 01:33:38 UTC+3, bitrex wrote: > Unfortunately this particular thing is for an embedded platform, so all > that cool automatic memory management stuff that assumes a system MMU is > out the door. On small embedded platforms such dynamic memory management for what we need smart pointers is typically avoided whatsoever. Fixed amount of external connections, fixed data, fixed queues, arrays and ring buffers. Also move does not give much advantages there. Moves (and whatever other ways to cache and to reuse) do give advantages on bigger systems with dynamic amount of threads, dynamic external connections, multi-media, unpredictable amounts of different kinds of data etc. |
bitrex <bitrex@de.lete.earthlink.net>: Aug 15 02:57PM -0400 On 08/15/2016 09:28 AM, Öö Tiib wrote: > Moves (and whatever other ways to cache and to reuse) do give advantages on > bigger systems with dynamic amount of threads, dynamic external connections, > multi-media, unpredictable amounts of different kinds of data etc. Yep. I try to instantiate all the objects that are required for the life of the program immediately on startup, and for whatever's left that needs to be dynamically allocated within a class, there's a fixed "buffer area" of the required size, and *const members that are used along with placement new. |
woodbrian77@gmail.com: Aug 15 11:40AM -0700 > > Or was your plan to make sure that only religious fanatics come to the > > meeting? > I welcome anyone that is interested. Is anyone interested in a C++ meeting in the St. Paul, Minnesota area? Brian Ebenezer Enterprises - Usain Bolt's middle name? St. Leo. http://webEbenezer.net |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment