Date: Tue, 25 Feb 2025 08:47:12 -0500
On Tue, Feb 25, 2025 at 6:46 AM Yongwei Wu via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> According to the current standard draft, is the [[indeterminate]]
> attribute not applicable to data members? [dcl.attr.indet] seems to
> imply so currently.
>
Notice that the direct result of [[indeterminate]] applies to the bytes of
storage underlying a complete object with automatic storage duration. Only
indirectly, it affects the results of objects in that storage if the object
has not been initialized and the bytes have not otherwise been assigned. A
non-static data member uses the storage of its class object, so
[[indeterminate]] wouldn't make sense there.
> 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).
-- Andrew Schepler
std-discussion_at_[hidden]> wrote:
> According to the current standard draft, is the [[indeterminate]]
> attribute not applicable to data members? [dcl.attr.indet] seems to
> imply so currently.
>
Notice that the direct result of [[indeterminate]] applies to the bytes of
storage underlying a complete object with automatic storage duration. Only
indirectly, it affects the results of objects in that storage if the object
has not been initialized and the bytes have not otherwise been assigned. A
non-static data member uses the storage of its class object, so
[[indeterminate]] wouldn't make sense there.
> 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).
-- Andrew Schepler
Received on 2025-02-25 13:47:26