Date: Sun, 10 Nov 2024 20:37:27 -0500
On Sun, Nov 10, 2024 at 8:05 PM Matthew House <mattlloydhouse_at_[hidden]>
wrote:
> On Sun, Nov 10, 2024 at 6:04 PM Brian Bi via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> > Unless I've misunderstood, the C23 draft appears to say that as soon as
> you write to any member of a struct, all padding bits are reset to
> unspecified values.
> >
> > 6.2.6.1/6: When a value is stored in an object of structure or union
> type, including in a member object, the bytes of the object representation
> that correspond to any padding bytes take unspecified values [...]
> >
> > That seems to prevent the use of `memcmp` for comparing the values of
> struct objects in most cases.
> >
> > Or is the C standard only talking about writes of struct type? (Which,
> as you probably know, don't exist in C++: an assignment operator, possibly
> a trivial one, is always called.)
>
> The question is, does "When a value is stored ... including in a
> member object" mean, "When a value is stored in an object, or in any
> object that is a member of that object", or "When a value is stored in
> an object, which may just happen to be a member of some other object"?
>
> I'd be inclined toward the latter (i.e., it only applies to padding
> within writes of struct type), since otherwise 6.2.6.1/7 would be
> totally redundant, and it would also cause silly things like data
> races if you memcmp() one member while concurrently writing another
> member a mile away. But a "compiler writers should be given as many
> liberties as possible" enthusiast would be inclined toward the former.
>
> N691, which introduced the clause, was primarily concerned with writes
> of struct type. It was listed in N2013 as having an unclear meaning
> (see Q60-Q72), but it looks like no one in WG14 discussed it much
> further. (Too bad wording cleanups are much less shiny than new
> features...) Gustedt interpreted it in N2159 as meaning "any object
> that is a member", but the minutes are very vague in the N2187
> minutes, and there don't seem to be any other WG14 interpretations
> about it. In practice, the big compilers don't write into padding on
> member writes since they're deathly afraid of data races on any level
> of the IR.
>
If all implementations are happy to avoid disturbing padding bytes upon
writes, then, paradoxically, we don't need to put specific words in the C++
standard that say that; they don't change simply because there is no
wording that can make them change.
However, for trivial copy operations, I think we need to say something. The
operation may or may not affect the padding bits of the destination.
>
> Matthew House
>
wrote:
> On Sun, Nov 10, 2024 at 6:04 PM Brian Bi via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> > Unless I've misunderstood, the C23 draft appears to say that as soon as
> you write to any member of a struct, all padding bits are reset to
> unspecified values.
> >
> > 6.2.6.1/6: When a value is stored in an object of structure or union
> type, including in a member object, the bytes of the object representation
> that correspond to any padding bytes take unspecified values [...]
> >
> > That seems to prevent the use of `memcmp` for comparing the values of
> struct objects in most cases.
> >
> > Or is the C standard only talking about writes of struct type? (Which,
> as you probably know, don't exist in C++: an assignment operator, possibly
> a trivial one, is always called.)
>
> The question is, does "When a value is stored ... including in a
> member object" mean, "When a value is stored in an object, or in any
> object that is a member of that object", or "When a value is stored in
> an object, which may just happen to be a member of some other object"?
>
> I'd be inclined toward the latter (i.e., it only applies to padding
> within writes of struct type), since otherwise 6.2.6.1/7 would be
> totally redundant, and it would also cause silly things like data
> races if you memcmp() one member while concurrently writing another
> member a mile away. But a "compiler writers should be given as many
> liberties as possible" enthusiast would be inclined toward the former.
>
> N691, which introduced the clause, was primarily concerned with writes
> of struct type. It was listed in N2013 as having an unclear meaning
> (see Q60-Q72), but it looks like no one in WG14 discussed it much
> further. (Too bad wording cleanups are much less shiny than new
> features...) Gustedt interpreted it in N2159 as meaning "any object
> that is a member", but the minutes are very vague in the N2187
> minutes, and there don't seem to be any other WG14 interpretations
> about it. In practice, the big compilers don't write into padding on
> member writes since they're deathly afraid of data races on any level
> of the IR.
>
If all implementations are happy to avoid disturbing padding bytes upon
writes, then, paradoxically, we don't need to put specific words in the C++
standard that say that; they don't change simply because there is no
wording that can make them change.
However, for trivial copy operations, I think we need to say something. The
operation may or may not affect the padding bits of the destination.
>
> Matthew House
>
-- *Brian Bi*
Received on 2024-11-11 01:37:42