C++ Logo

std-discussion

Advanced search

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

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Sun, 09 Mar 2025 21:31:32 +0000
On 26 February 2025 01:46:03 GMT, Yongwei Wu via Std-Discussion <std-discussion_at_[hidden]> wrote:
>Manually adding P2795 author into the discussion.
>
>On Tue, 25 Feb 2025 at 21:47, Andrew Schepler <aschepler_at_[hidden]> wrote:
>
>>
>> Suppose the following class:
>>>
>>> class Obj {
>>> public:
>>> Obj() = default;
>>> int calculate(int param)
>>> {
>>> // Some calculation that utilizes the scratch buffer
>>> }
>>>
>>> private:
>>> int x{};
>>> int y{};
>>> std::byte scratch_buffer[2048]; // [[indeterminate]] intended
>>> };
>>>
>>> Currently, Obj::scratch_buffer will contain indeterminate values.
>>
>>
>> Maybe. If an object of type Obj has static storage duration,
>> scratch_buffer will initially contain zeroes. If it has dynamic storage
>> duration, scratch_buffer will initially contain indeterminate values, and
>> you can't change that. In C++23 and earlier, if the object of type Obj has
>> automatic storage duration, scratch_buffer initially contains indeterminate
>> values. In the current C++ draft, for automatic storage duration, it's the
>> presence or absence of [[indeterminate]] on that Obj-type definition which
>> says whether scratch_buffer has indeterminate or erroneous values.
>>
>>
>>> In C++26, will there be a way for it to opt out of the erroneous value
>>> initialization, sans requiring the user to change the client-side
>>> code?
>>>
>>
>> Unlikely, but note "erroneous behavior" resulting from use of an erroneous
>> value is in a sense "better" than the "undefined behavior" resulting from
>> use of an indeterminate value. An erroneous value is unpredictable but at
>> least behaves as one specific and consistent value, whereas use of an
>> indeterminate value could cause any results for the whole program. As far
>> as I know, this better describes the actual situation in modern
>> architectures (without a "trap representation") with compilers configured
>> to produce efficient executable code (maybe not with a tool or compiler
>> mode for strong linting).
>>
>
>I think it can be a performance concern to certain people. It completely
>makes sense to me to make the default behaviour safer, but it is another
>story that one has to change the *client-side* code in order to make the
>code perform as well in the age of C++26. (Changing the implementation code
>is OK for me.)
>
>And the [[indeterminate]] attribute actually does not really make sense in
>a declaration like `Obj obj [[indeterminate]];`, as it is not the purpose
>of the code to allow `obj` to contain indeterminate values. It just happens
>that it uses a scratch buffer, which is an implementation detail of the
>class Obj.
>
>Seriously, should it be proposed that [[indeterminate]] be allowed on data
>members? Was it not thought of, or thought of but abandoned due to
>technical or other difficulties?

There is also an example datasructure in P3530 that could make use of [[indeterminate]] on a non-static data member, it's described here:
 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3530r0.html#background

This databstructure could use both [[indeterminate]] for efficiency and their proposed "read_maybe_uninitialized" for correctness.

IMO [[indeterminate]] on non-static data members would make a lot of sense.

Lénárd

Received on 2025-03-09 21:31:42