Date: Tue, 11 Mar 2025 22:04:00 +0800
On Mon, 10 Mar 2025 at 17:36, Giuseppe D'Angelo via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> On 25/02/2025 12:45, Yongwei Wu via Std-Discussion wrote:
> > Currently, Obj::scratch_buffer will contain indeterminate 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?
>
> 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).
The problem is not the avoidance of UB, but the potential harm to
performance. And I do not want the user to use the [[indeterminate]]
attribute, which is awkward and simply wrong in semantics.
> Do you have a use case for always wanting UB instead of EB for
> uninitialized reads of a non-static data member?
Was my example not good enough? OK, a more real one. But keep in mind
I do not want UB, just that I do not want the compiler to initialize
some uninitialized data members.
I wrote a BigFixedString for test purposes, and google-benchmarked it.
Two versions are posted online:
https://quick-bench.com/q/9QkL9cSkqHSi2pb5A-TTkglbaDU
https://quick-bench.com/q/MmE9IwFaXqjz_gFnEmSK8s3qFrA
The difference is that one has a member `char buffer_[128];`, and the
other `char buffer_[128]{};`. Of course, the uninitialized data are
never read.
Currently the benchmark results show the performance difference is
about 90:54. Always initializing seems to have a 65% penalty on
performance.
> On the other hand: even in pre-C++26 modes, compilers have hardening
> options that fill the storage for automatic variables with certain bit
> patterns (such as -ftrivial-auto-var-init), and also have
> compiler-specific attributes to opt-out in case this filling gets too
> expensive (such as [[gnu::uninitialized]]). For certain use cases it may
> make sense to disable such filling, and to do so in a centralized manner
> (by applying the attribute to a class, or a constructor, or a data
> member, etc., that's open for debate).
The problem is that EB (and thus automatic initialization of automatic
objects) will become the default in C++26, and I want a
user-transparent way to get out of this default behaviour for certain
data members (only). Yup, making the attribute applicable to
non-static data members is exactly what I want.
<std-discussion_at_[hidden]> wrote:
>
> On 25/02/2025 12:45, Yongwei Wu via Std-Discussion wrote:
> > Currently, Obj::scratch_buffer will contain indeterminate 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?
>
> 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).
The problem is not the avoidance of UB, but the potential harm to
performance. And I do not want the user to use the [[indeterminate]]
attribute, which is awkward and simply wrong in semantics.
> Do you have a use case for always wanting UB instead of EB for
> uninitialized reads of a non-static data member?
Was my example not good enough? OK, a more real one. But keep in mind
I do not want UB, just that I do not want the compiler to initialize
some uninitialized data members.
I wrote a BigFixedString for test purposes, and google-benchmarked it.
Two versions are posted online:
https://quick-bench.com/q/9QkL9cSkqHSi2pb5A-TTkglbaDU
https://quick-bench.com/q/MmE9IwFaXqjz_gFnEmSK8s3qFrA
The difference is that one has a member `char buffer_[128];`, and the
other `char buffer_[128]{};`. Of course, the uninitialized data are
never read.
Currently the benchmark results show the performance difference is
about 90:54. Always initializing seems to have a 65% penalty on
performance.
> On the other hand: even in pre-C++26 modes, compilers have hardening
> options that fill the storage for automatic variables with certain bit
> patterns (such as -ftrivial-auto-var-init), and also have
> compiler-specific attributes to opt-out in case this filling gets too
> expensive (such as [[gnu::uninitialized]]). For certain use cases it may
> make sense to disable such filling, and to do so in a centralized manner
> (by applying the attribute to a class, or a constructor, or a data
> member, etc., that's open for debate).
The problem is that EB (and thus automatic initialization of automatic
objects) will become the default in C++26, and I want a
user-transparent way to get out of this default behaviour for certain
data members (only). Yup, making the attribute applicable to
non-static data members is exactly what I want.
Received on 2025-03-11 14:04:14