Friday, August 12, 2016

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

jacobnavia <jacob@jacob.remcomp.fr>: Aug 12 08:57AM +0200

The chief developper of clang has pointed out that this example CHANGES
BEHAVIOR between c++ 2008 and c++ 2011
 
#include <iostream>
struct S { int n; };
struct X { X(int) {} };
void f(void *) {
std::cerr << "Pointer!\n";
}
void f(X) {
std::cerr << "X!\n";
}
int main() {
f(S().n);
}
 
In c++ 2008 it will print X!, in c++ 2011 it will print Pointer!
 
The explanation is so complicated that not even the lead developper of
clang is sure about it. He doesn't seem to understand either that the
complexity of c++ has gotten SO OUT OF HAND that not even he understands
what he is doing.
 
Does anyone here have a clear explanation of what is happening?
 
Actually I am very pleased by this c++ behavior:
 
You need people to continuosly recompile old programs because the
language changes underneath your feets and needs people to recompile it
in the new language they have just created.
 
Yes, a NEW LANGUAGE, as the lead developer insists several times in his
talk.
 
Contrary to many people I find this behavior EXTREMELY USEFUL. It has
provided me with a job for the last months recompiling old c++ stuff
with the new compilers. I am surely not an expert (nobody is, not even
the lead developper of clang!) but I am starting to get used to it.
 
I am sure the new c++ 2014 will provide me plenty of job opportunities.
"Öö Tiib" <ootiib@hot.ee>: Aug 12 01:08AM -0700

On Friday, 12 August 2016 09:57:23 UTC+3, jacobnavia wrote:
> complexity of c++ has gotten SO OUT OF HAND that not even he understands
> what he is doing.
 
> Does anyone here have a clear explanation of what is happening?
 
I think that C++11 should also print X!. Where you took that from?
 
> with the new compilers. I am surely not an expert (nobody is, not even
> the lead developper of clang!) but I am starting to get used to it.
 
> I am sure the new c++ 2014 will provide me plenty of job opportunities.
 
It is unfortunately very similar with C compilers. An actual behavior
(defined or undefined) will change between versions and things stop
working.
 
Same is with platforms. I was thinking that Windows changes between every
version too much until I had to develop some apps for platforms of Apple. :)
Windows is extremely stable platform.
 
So when some bigger code base is built on some newer version of compiler
(typically to achieve that it runs on some new version of platform) then
there will be some new compiling errors or warnings and some unit
tests also always break and there will be work to do.
jacobnavia <jacob@jacob.remcomp.fr>: Aug 12 11:11AM +0200

Le 12/08/2016 à 10:08, Öö Tiib a écrit :
> I think that C++11 should also print X!. Where you took that from?
 
Chandler-Carruth
Lead developper of the "clang" compiler project. And before you write "I
think that..." can you compile that?
 
Thanks
Ben Bacarisse <ben.usenet@bsb.me.uk>: Aug 12 10:48AM +0100

> int main() {
> f(S().n);
> }
 
Interesting question. It seems to boil down to whether S().n is a
constexpr with value 0 (I think it is) and whether f(<constexpr with
value 0>) should call f(void *) (I have no idea!).
 
Both g++ and clang++ print "X!" for this variant of the code:
 
#include <iostream>
struct S { int n; };
struct X { X(int) {} };
void f(void *) {
std::cerr << "Pointer!\n";
}
void f(X) {
std::cerr << "X!\n";
}
int main() {
constexpr int c = 0;
f(c);
}
 
Should they both print "Pointer!"?
 
<snip>
--
Ben.
m.labanowicz@gmail.com: Aug 12 03:39AM -0700

Hi,
 
I have another results, it seems that c++11 corrects types handling:
 
--{beg:test}---------------------------------------------
$ cat main.cpp
 
#include <iostream>
 
int const value = VALUE;
 
struct X {
X(int) {}
};
 
void f(void *) {
std::cerr << "Pointer!\n";
}
 
void f(X) {
std::cerr << "X!\n";
}
 
int main() {
f(value);
}
 
$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
$ clang++ --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
 
$ g++ main.cpp -DVALUE=0 && ./a.out
Pointer!
$ g++ main.cpp -DVALUE=1 && ./a.out
X!
$ g++ main.cpp -DVALUE=0 -std=c++11 && ./a.out
X!
$ g++ main.cpp -DVALUE=1 -std=c++11 && ./a.out
X!
$ clang++ main.cpp -DVALUE=0 && ./a.out
main.cpp:19:5: warning: expression which evaluates to zero treated as a null pointer constant of type 'void *'
[-Wnon-literal-null-conversion]
f(value);
^~~~~
1 warning generated.
Pointer!
$ clang++ main.cpp -DVALUE=1 && ./a.out
X!
$ clang++ main.cpp -DVALUE=0 -std=c++11 && ./a.out
X!
$ clang++ main.cpp -DVALUE=1 -std=c++11 && ./a.out
X!
--{eof:test}---------------------------------------------
 
Regards
 
--
Maciej Labanowicz
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 12 12:54PM +0200

On 12.08.2016 08:57, jacobnavia wrote:
> f(void *) { std::cerr << "Pointer!\n"; } void f(X) { std::cerr <<
> "X!\n"; } int main() { f(S().n); }
 
> In c++ 2008 it will print X!, in c++ 2011 it will print Pointer!
 
There is no C++ 2008, but there is a C++ 2003; presumably that's what
you mean.
 
 
> The explanation is so complicated that not even the lead developper
> of clang is sure about it.
 
In
 
http://stackoverflow.com/a/23048287/464581
 
it's maintained that C++11 nullpointer constants have to be literals, as
opposed to C++03 constant expressions.
 
I can't find that in the standard (N3290 draft), so, even though that's
what I believed until now, I think it's a misunderstanding based on the
standard's term "literal type".
 
But for sure there was some change.
 
 
> He doesn't seem to understand either that the complexity of c++ has
> gotten SO OUT OF HAND that not even he understands what he is doing.
 
Oh my.
 
 
> Does anyone here have a clear explanation of what is happening?
 
I think C++11 was OK but C++14 included many local kludge-like fixes and
kludge-like "improvements". It seems to me the language is shattering
into disconnected small pieces that sometimes end up being incompatible
with each other, and anyway introduce great complexity. I think what
happened was that the people with long views who cared for a clean
language, got too old and more or less dropped out, while bright new
Asperger's syndrome good-at-memorization folks got into the act.
 
But maybe you're asking specifically about nullpointer constants.
 
I'm not sure exactly where, but the change seems to reside with the
definition of /integral constant expression/. Both C++03 and C++11
define a null pointer constant as an integral constant expression,
except that C++11 additionally allows a std::nullptr_t prvalue.
 
 
Cheers & sorry for not having more clear-cut facts,
 
- Alf
legalize+jeeves@mail.xmission.com (Richard): Aug 12 04:59PM

[Please do not mail me a copy of your followup]
 
jacob@jacob.remcomp.fr spake the secret code
 
>Chandler-Carruth
>Lead developper of the "clang" compiler project. And before you write "I
>think that..." can you compile that?
 
Chandler Carruth is the lead developer of the C++ tools team at
google. I don't think clang itself can be considered to have a
single lead developer. Different people take responsibility for
different areas. See
<https://github.com/llvm-mirror/llvm/blob/master/CODE_OWNERS.TXT>
<https://github.com/llvm-mirror/clang/blob/master/CODE_OWNERS.TXT>
<https://github.com/llvm-mirror/clang-tools-extra/blob/master/CODE_OWNERS.TXT>
etc.
 
Getting back to the example code, my takeaway is two-fold:
 
1) It's been a well known problem that overloading functions for a pointer
type and an integer type leads to surprises. Is NULL an integer or is
it a pointer? It depends on the implementation. This is one of the
reasons why nullptr/nullptr_t was added to the language. Overloading
on both of these types as the only difference in the signature is
going to be surprising unless you static_cast<> appropriately.
 
2) Single argument constructors that allow implicit conversion between
types is also a well known problem that leads to surprises. All the
C++ "lint" like tools I know of report warnings or errors for such
constructors and advise you to make the constructor explicit.
 
This code wouldn't lead to such surprising results if it had been
written to avoid these well known areas of surprise.
--
"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 12 01:19PM -0700

On Friday, August 12, 2016 at 5:54:31 AM UTC-5, Alf P. Steinbach wrote:
> happened was that the people with long views who cared for a clean
> language, got too old and more or less dropped out, while bright new
> Asperger's syndrome good-at-memorization folks got into the act.
 
I consider myself to have a long view of things and I had to
stay out in order to survive. If you can't join 'em, beat 'em.
 
Now is the time for a group of G-dly men and women to work
together to help C++.
 
https://groups.google.com/forum/#!searchin/comp.lang.c$2B$2B/comments$20$20%22scott$20meyers%22%7Csort:date/comp.lang.c++/5q7jqe6GPiA/NUfq1NZ1R1sJ
 
Brian
Ebenezer Enterprises
 
"The righteous will flourish like a palm tree,
they will grow like a cedar of Lebanon;
planted in the house of the L-rd,
they will flourish in the courts of our G-d.
 
They will still bear fruit in old age,
they will stay fresh and green,
proclaiming, "The L-rd is upright;
He is my Rock, and there is no wickedness in Him." Psalms 92:12-15
 
http://webEbenezer.net
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Aug 12 09:48PM +0100

> proclaiming, "The L-rd is upright;
> He is my Rock, and there is no wickedness in Him." Psalms 92:12-15
 
> http://webEbenezer.net
 
Brian, fuck off.
 
/Flibble
woodbrian77@gmail.com: Aug 12 02:43PM -0700

On Friday, August 12, 2016 at 3:48:53 PM UTC-5, Mr Flibble wrote:
 
If you repent, Leigh, you could join the group.
C.S. Lewis said that G-d told him to, "Put down
your gun and we'll talk."
 
I support law abiding citizens having guns so don't
want to give the wrong idea by quoting that.
Lewis could either make peace with G-d or run away
with his gun.
jacobnavia <jacob@jacob.remcomp.fr>: Aug 12 11:49PM +0200

Le 12/08/2016 à 10:08, Öö Tiib a écrit :
> It is unfortunately very similar with C compilers. An actual behavior
> (defined or undefined) will change between versions and things stop
> working.
 
Yes, true.
 
But I do not know how many orders of magnitude less than in c++, you
will agree with me.
 
C is VERY stable language, and software written in C stands the time
test. A C beautifier program is still running in the lcc-win IDE, code
written in the eighties.
jacobnavia <jacob@jacob.remcomp.fr>: Aug 12 11:58PM +0200

> I support law abiding citizens having guns
 
Yes, you must live in the U.S.A. In that country, people kill themselves
with their guns for nothing. Everyone has a gun and everyone is shooting
around. A grand parent kills his grand daughter because he mistakenly
thought it was an intruder.
 
Mass shootings everywhere, they are the latest gun fad.
 
Violence is destroying the basic assumptions about society but the
shooting goes on and on.
 
Yes, we should fight the shooting with...
 
MORE GUNS.
 
LAW ABIDING CITIZENS do not have guns in most civilized countries.
Happily for us, we do not live near those "law abiding" citizens ready
to shoot anyone that approaches.
 
This sickness has contaminated the whole country and the shooting has
increased, multiplied by the media and all people like you:
 
> I support law abiding citizens having guns
 
you said.
 
Gun happy.
jacobnavia <jacob@jacob.remcomp.fr>: Aug 13 12:19AM +0200

Le 12/08/2016 à 08:57, jacobnavia a écrit :
> int main() {
> f(S().n);
> }
 
Look I do not know c++ but anyway... I think in that language programs
start in the "main" function. We start there then.
 
We have a function call of an "f" function, where you have two possible
alternatives: One that receives a void * (a pointer to "anything") and
another that receives an "X", i.e. a structure that has only a
constructor. This constructor receives an int as argument.
 
To know what is being passed to "f" (data that will determine the one
"f" being called) we have to simply evaluate the expression:
 
S().n
 
This looks like the constructor of "S" being called to make an "S", then
using the result to acces its "n" member above.
 
This is the default constructor because nowhere is a constructor for "S"
in scope. And I suppose that the default constructor always initializes
ints to zero. Then, the outcome of a call to an "S" constructor in this
scope is fixed, since it is the default constructor: zero.
 
The type of the expression is then the integer zero, an ambiguous value
now, since can be a null pointer AND an integer. According to obscure
rules that nobody really understands, an integer is an input for the
constructor of "X" objects, and that can be used to build an "X", that
is passed to the overloaded function in scope that prints X!
 
I remember when I was young and naive, and started to read the rules for
operator overloading in the c++ standard. They went for pages and pages
of stuff like a topological sort of all classes in scope.
 
Well they ARE C++ heads, that is for sure. But now we have since a long
long time reached the level where nobody understands anything any more
and a 12 line program suffices for provoking and big embarrased silence.
 
Now, just out of curiosity...
 
Where did I go wrong?
 
Thanks
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 13 12:40AM +0200

On 13.08.2016 00:19, jacobnavia wrote:
> and a 12 line program suffices for provoking and big embarrased silence.
 
> Now, just out of curiosity...
 
> Where did I go wrong?
 
Just a technicality: `S()` is not invoking a default constructor,
because there isn't one, but is "value initialization", which reduces to
zero-initalization in this case. So the outcome is as you described,
just via a slightly different mechanism (unfortunately it does matter in
some situations, more complexity...). The difference between C++
versions appears to be that this zero value can be regarded as a compile
time integer 0, a "constant expression" 0 in C++11, but not in C++03,
which has less smarts.
 
IMO the same phenomenon, of too "smart" things, is going to hit us via
appliances, the internet of things, in just some years.
 
Watch for when your fridge is hacked by some silly teenagers who target
everyone who buys a brand of beer that they don't like, via an attack
vector provided by the extreme complexity of the fridge's OS.
 
 
Cheers!,
 
- Alf
Richard Damon <Richard@Damon-Family.org>: Aug 11 11:08PM -0400

On 8/9/16 5:29 PM, Melzzzzz wrote:
> destructor
> [bmaxa@maxa-pc examples]$
 
> Is this defect, and what is point of moving around, if not?
 
One very simple reason. At the point the object life time ends, how can
the compiler be certain, in all cases, if the object has been moved from?
 
There might be multiple paths, some which move and some which don't.
A reference to the object might have been passed to a function, which
you can't see into at this point in the code, so that might have moved
or might not have.
 
The only solution I can think of to fully bypass the destructor if the
object was moved from is to add a flag to every object to remember this.
Much simpler to just call the destructor.
 
Also, the move constructor is ALLOWED, but not required to take the
resource out of the object. It is perfectly valid for a move constructor
to be identical in function to a copy constructor, so the destructor
does need to be run to make sure the resources are freed.
Good Guy <hello.world@example.com>: Aug 12 01:26AM +0100

On 11/08/2016 09:26, David Brown wrote:
> such subjects are the norm in entertainment groups like
> sci.electronics.design (I know you post there, because I read it too
> sometimes - for entertainment).
 
I would "followup-to" this one to:
 
<news://nntp.aioe.org/misc.survivalism>
 
That is where all the entertainment, insults and good & bad language
resides.
 
No religion; No politics and No bull-shitting here.
 
 
--
With over 350 million devices now running Windows 10, customer
satisfaction is higher than any previous version of windows.
bitrex <bitrex@de.lete.earthlink.net>: Aug 11 09:03PM -0400

On 08/11/2016 04:26 AM, David Brown wrote:
> such subjects are the norm in entertainment groups like
> sci.electronics.design (I know you post there, because I read it too
> sometimes - for entertainment).
 
Yes, I did. I mistakenly posted this to here, rather than my usual
"politcal drivel" group - since everyone else does I have appearances to
keep up...; )
 
comp.lang.c++ has my apologies.
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: