Date: Tue, 11 Mar 2025 19:51:10 +0000
On 11 March 2025 15:11:34 GMT, Brian Bi via Std-Discussion <std-discussion_at_[hidden]> wrote:
>On Tue, Mar 11, 2025 at 10:04 AM Yongwei Wu via Std-Discussion <
>std-discussion_at_[hidden]> wrote:
>
>> 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.
>>
>
>I'm uncomfortable with the idea of a class author being able to override
>the user's choice to *not* declare a local variable [[indeterminate]], by
>placing [[indeterminate]] on the declaration of a non-static data member
>and thus making part of the object's storage indeterminate anyway. Note
>that even if it's just in a private member, there will still be UB if the
>object is used as the source of `memcpy`.
It's the class author's job to do the proper encapsulation. If memcpy is indeed UB (is it really?), then maybe such classes must not be trivially copyable. I agree that it's error prone, but if a class requires some indeterminate storage for efficient operation, then it could be less error prone to implement it correctly once within the class than the user applying [[indeterminate]] at each usage.
>
>
>> --
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>
>
>On Tue, Mar 11, 2025 at 10:04 AM Yongwei Wu via Std-Discussion <
>std-discussion_at_[hidden]> wrote:
>
>> 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.
>>
>
>I'm uncomfortable with the idea of a class author being able to override
>the user's choice to *not* declare a local variable [[indeterminate]], by
>placing [[indeterminate]] on the declaration of a non-static data member
>and thus making part of the object's storage indeterminate anyway. Note
>that even if it's just in a private member, there will still be UB if the
>object is used as the source of `memcpy`.
It's the class author's job to do the proper encapsulation. If memcpy is indeed UB (is it really?), then maybe such classes must not be trivially copyable. I agree that it's error prone, but if a class requires some indeterminate storage for efficient operation, then it could be less error prone to implement it correctly once within the class than the user applying [[indeterminate]] at each usage.
>
>
>> --
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
>
>
Received on 2025-03-11 19:51:25