C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] indeterminate value

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Sat, 20 Feb 2021 12:10:03 +0100
On 20/02/2021 10.06, Uecker, Martin via Liaison wrote:
> Am Samstag, den 20.02.2021, 09:30 +0100 schrieb Jens Gustedt via Liaison:
>> Jens,
>>
>> on Fri, 19 Feb 2021 22:31:15 +0100 you (Jens Maurer via Liaison
>> <liaison_at_[hidden]>) wrote:
>>
>>> So, for anything but "unsigned char", even looking at
>>> an uninitialized value is undefined behavior in C++
>>> (in C parlance, there might be a trap representation).
>>
>> It is a bit more complicated in C, because of this weird `register`
>> rule and because of pointers:
>
> The C rules are a bit weird, but overall make sense to me.
>
> The C++ rules seem far more problematic: The forbid useful
> behavior that C allows. For example, computing as hash for
> a struct including padding bytes and comparing it later.

Yes, that doesn't work reliably in C++.

> I similar issue might exist for atomic_compare_exchange.
> (I do not know what they did there to fix this).

Specification-wise, we simply say that you ignore padding
bytes in the comparison ([atomics.types.operations] p23;
look for "value representation"). Practically speaking, the
implementation might invoke compiler magic to reliably zero
the padding bytes before doing the comparison.

> At the same time it does not allow simple detection of
> reads of uninitialized automatic variables because you
> to take all this weird rules for unsigned char into
> account.

I think the C++ rules here are fairly tractable, since you
only need to analyze a single expression at a time for
determining whether the uninitialized "unsigned char"
read is a good one or a bad one.

> This does strike me as very unfortunate design
> choice (which also made language more different from C).

The "could have been declared with register" rule in C
doesn't seem friendly either, because a seemingly benign
no-op has spooky effects at a distance:

void f()
{
  int i;

  [... some lines of code...]

  if (false)
    (void)&i; // ah, address was taken, go back to the beginning of "f" and re-analyze all the code
}

(C++ doesn't have "register" anymore, because compilers can do it
much better automatically.)

Jens

Received on 2021-02-20 05:10:18