C++ Logo

std-discussion

Advanced search

Re: Is [[indeterminate]] not applicable to data members?

From: Andrew Schepler <aschepler_at_[hidden]>
Date: Tue, 11 Mar 2025 15:49:25 -0400
On Mon, Mar 10, 2025 at 5:36 AM Giuseppe D'Angelo via Std-Discussion <
std-discussion_at_[hidden]> wrote:

>
> I think there's a misunderstanding here: EB doesn't mandate that the
> storage for an automatic variable gets initialized in any specific way.
> It just changes the semantics of what happens if you read from an
> uninitialized automatic variable (you get EB). The [[indeterminate]]
> attribute restores the pre-C++26 semantics (you get UB).
>

That's what I thought as well. I don't see anything in the draft Standard
implying programs must write bytes into the storage of erroneous values.
The main thing it does is change the required behavior of a buggy program
from the UB "anything could happen" to the EB "the behavior is consistent
for some specific value of the uninitialized object". It could still have
other performance implications since compiler optimization can't assume a
used value is not indeterminate.

For this TU below, I see with g++ -O3 and clang++ -O3 that test(false,
true) calls f(3). This existing behavior seems like it's also a valid
result of EB, though obviously it's not because of a general rule about
initializing bytes as "3".

extern void f(int);

// test(false, true) has UB in C++23, EB in C++26
void test(bool a, bool b) {
unsigned char c;
if (a) {
c = 3;
f(1);
}
if (b) {
f(c);
}
}

However, P2795R3 does say "The automatic storage for an automatic variable
is always fully initialized, which has potential performance implications.
P2723R1 discusses the costs in some detail." And P2723R1 describes
performance costs (and gains!) from initializing bytes, and security
concerns about leaking data from stack memory via uninitialized objects and
padding bytes.

So I'm not sure: Is it the intent or not that typical-architecture code
must do extra initialization of some sort for bytes with erroneous value?
Does the draft Standard actually say that? It says each erroneous value "is
determined by the implementation independently of the state of the
program", but that might have an issue in that the Standard normally
prescribes the C++ abstract machine ([intro.abstract]), which doesn't have
any equivalent of left-over byte values in the stack influenced by previous
program execution.

-- Andrew Schepler

Received on 2025-03-11 19:49:42