C++ Logo


Advanced search

Re: [wg14/wg21 liaison] (SC22WG14.19264) C memory object model study group - uninitialised reads and padding

From: Uecker, Martin <Martin.Uecker_at_[hidden]>
Date: Wed, 14 Apr 2021 21:45:27 +0000
Am Mittwoch, den 14.04.2021, 23:16 +0200 schrieb Jens Maurer:
> On 14/04/2021 23.06, Uecker, Martin wrote:
> > I wonder why C++ made the change to inderminate values in C++14?
> > (As I understand it, this is where it diverged from C).
> > This seems to cause a lot of trouble now and, quite frankly,
> > I do not see a real benefit in C++'s rules for indeterminate
> > values that are worth all the trouble.
> The change towards "indeterminate value" is more a specification
> clarification than an actual semantics change.

Thanks, I do not know the history of C++ so well.

> In C++11, we had in the section talking about lvalue-to-rvalue
> conversion (i.e. reading a scalar value from memory):
> "If the object to which the glvalue refers is not [...], or if
> the object is uninitialized, a program that necessitates this
> conversion has undefined behavior."
> Questions arose whether that would also apply to bytes,
> and how that would interact with a user-written memcpy
> look-alike, and whether the property "uninitialized"
> was retained even after an assignment to that object.
> The introduction of "indeterminate value" formalized
> the behavior in this area.

If I understand it correctly, C++ now has indeterminate
values that can be propagated (assignment, etc.).

So if you have a struct and padding bytes which are
considered indeterminate, you can still copy the
struct byte by byte, but would propagate the
indeterminate state of the padding to the copy.

This may have the advantage that a compiler can
decompose the struct into its members and pretend
the padding does not exist even though it is
copied byte-by-byte.

What I wondering about is whether the this optimization
is so useful that it is not worth all the disadvantages.

If one is not interested in the byte representation,
one can copy a struct using assignment and simply not
use a memcpy. Then also a C compiler can pretend
the padding does not exist and optimize it away.

On the other hand, a programmer who wants to
copy/compare the representation bytes can do this
using character pointers and/or memcpy/memcmp
and this works as expected as accessing the
padding bytes in this way is not UB. This is
useful and cmpxchg is just one of many examples
where this is useful.

So a C programmer gets both: The optimization
opportunity (when using struct assignment) but
also the low-level control (when accessing the
byte representation).


Received on 2021-04-14 16:45:36