Monday, August 15, 2016

Digest for comp.lang.c++@googlegroups.com - 22 updates in 3 topics

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: