Thursday, April 4, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 04 07:44AM +0200

> possibility that they alias the same location. Since the behavior would
> be undefined in those cases, ignoring that possibility would not rende
> the implementation non-conforming.
 
Thanks, now it appears to be clear where the nonsense comes from, namely
the "optimization" in the GCC compiler.
 
They've wasted quite some zillions of hours of programmer's time on that
kind of "optimization"s that often (when it kicks in) makes the code do
an unintended and unanticipated thing, without any diagnostic.
 
It makes the compiler unreliable, but IME it can't be discussed without
a lot of heat ensuing, and circular logic + other fallacies offered up.
As I see it, that's because somehow a majority of GCC users have been
convinced that regarding this issue they're on the same team as the
compiler writers. Sort of like the majority of Trump's voters think
they're on the same team as the billionaires that exploit them.
 
 
Cheers!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Apr 04 11:05AM +0200

On 01/04/2019 08:36, Bonita Montero wrote:
> }
 
> .. the iterators to the vector remain valid until the place I cut
> the vector.
 
That is true for standard erase also. But iterators at or after the
erase point are not valid. You can't assume they point to shifted
values, or other elements.
 
<https://en.cppreference.com/w/cpp/container/vector/erase>
David Brown <david.brown@hesbynett.no>: Apr 04 11:18AM +0200

On 01/04/2019 14:31, Paavo Helde wrote:
 
> If so, why does the standard contain special verbiage that the iterators
> to elements *before* the erased range remain valid? It would be much
> simpler to say that an erase() call will invalidate all iterators.
 
Isn't it just a combination of "erase leaves elements before the erase
point untouched, but changes the vector after that" and "if an iterator
points to part of a container that gets structural changes, it is invalid" ?
 
When you have associative containers, erase only (logically) changes the
erased items - iterators to guaranteed unchanged parts are still valid.
 
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 04 11:44AM +0100

>> the implementation non-conforming.
 
> Thanks, now it appears to be clear where the nonsense comes from,
> namely the "optimization" in the GCC compiler.
 
That's unlikely. The wording in the C standard predates gcc.
 
--
Ben.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 04 01:05PM +0200

> That is true for standard erase also. But iterators at or after the
> erase point are not valid. You can't assume they point to shifted
> values, or other elements.
 
That's a stupid specification because it's easy to implement the erase
-method in a way that only iterators to the last elements of the vector
become invalid (equal to the number you erased). I've already given an
implementation in this thread that makes this guarantee.
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 04 08:04AM -0400

On 4/4/19 1:44 AM, Alf P. Steinbach wrote:
>> the implementation non-conforming.
 
> Thanks, now it appears to be clear where the nonsense comes from, namely
> the "optimization" in the GCC compiler.
 
I made no mention of gcc, or any other particular compiler. I have no
idea whether any compiler actually performs such an optimization. I was
giving it only as an example of how you might realistically see
unexpected behavior due to the fact that such code has undefined behavior.
 
Keep in mind that this "nonsense" was explicitly endorsed by the C
committee in DR #017, justifying that ruling by citing wording from the
C90 standard that has continued to be present in every version of both
the C and C++ standards. They added wording in section J.1 of C99
clarifying that this was indeed the intent of the committee. Neither the
C committee nor the C++ committee has ever, to the best of my knowledge,
repudiated the resolution of that DR.
Paavo Helde <myfirstname@osa.pri.ee>: Apr 04 03:04PM +0300

On 4.04.2019 14:05, Bonita Montero wrote:
> -method in a way that only iterators to the last elements of the vector
> become invalid (equal to the number you erased). I've already given an
> implementation in this thread that makes this guarantee.
 
If something is easy it does not automatically mean it should be done.
 
For example, composing SQL statements by string concatenation. Or
copy-pasting a large function to make a small modification.
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 04 08:13AM -0400

On 4/4/19 6:44 AM, Ben Bacarisse wrote:
 
>> Thanks, now it appears to be clear where the nonsense comes from,
>> namely the "optimization" in the GCC compiler.
 
> That's unlikely. The wording in the C standard predates gcc.
 
I'd been planning to say the same thing, but when I checked on
Wikipedia, it said that the first version of gcc came out in 1987, 2
years before the first version of the C standard.
Note that while the wording in the C standard dates back to C89, the
fact that it has this meaning was sufficiently unclear that it had to be
resolved with DR #017 in 1992, 5 years after gcc came out.
I sincerely doubt that gcc had anything in particular to do with that
decision, but the timing of the events does not rule out that possibility.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 04 02:43PM +0200

> If something is easy it does not automatically mean it should be done.
 
I already said that this implications won't make any restriction on the
implementation.
 
> For example, composing SQL statements by string concatenation.
> Or copy-pasting a large function to make a small modification.
 
This analogies don't fit.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 04 01:55PM +0100


> I'd been planning to say the same thing, but when I checked on
> Wikipedia, it said that the first version of gcc came out in 1987, 2
> years before the first version of the C standard.
 
I could claim (though I won't!) that I was talking about the first C
standard -- the reference manual in K&R1 -- which has similar wording,
though it does not explicitly say the result is undefined. K&R2 (1988)
adds such an explicit remark with no comment about this being a change,
and the list of changes from K&R1 does not include it.
 
It's not reasonable to think that K&R (or the committee) added those
words because gcc, in it's first few months, had decided to do
sophisticated alias analysis.
 
> Note that while the wording in the C standard dates back to C89, the
> fact that it has this meaning was sufficiently unclear that it had to be
> resolved with DR #017 in 1992, 5 years after gcc came out.
 
Right. That means that the "it comes from gcc" argument would require
that it was sufficiently clear the the gcc team (despite being,
apparently unclear to others) that they were prepared to break code that
did not have the same understanding.
 
> I sincerely doubt that gcc had anything in particular to do with that
> decision, but the timing of the events does not rule out that
> possibility.
 
ACK.
 
--
Ben.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 04 11:56AM +0200

I've re-implemented the class more usable and POSIX-compilable:
 
#if defined(_MSC_VER)
#include <Windows.h>
#include <intrin.h>
#elif defined(__unix__)
#include <semaphore.h>
#include <pthread.h>

No comments: