home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,456 of 243,242   
   Tim Rentsch to Keith Thompson   
   Re: Nice way of allocating flexible stru   
   15 Dec 25 11:24:29   
   
   From: tr.17687@z991.linuxsc.com   
      
   Keith Thompson  writes:   
      
   > BGB  writes:   
   >   
   >> On 10/8/2025 1:35 AM, Kaz Kylheku wrote:   
   >>   
   >>> Jonas Lund of https://whizzter.woorlic.org/ mentioned this   
   >>> trick in a HackerNews comment:   
   >>> Given:   
   >>>    struct S {   
   >>>      // ...   
   >>>      T A[];   
   >>>    };   
   >>> Don't do this:   
   >>>    malloc(offsetof(S, A) + n * sizeof (T));   
   >>> But rather this:   
   >>>    malloc(offsetof(S, A[n]));   
   >>> It's easy to forget that the second argument of offsetof is a   
   >>> designator, not simply a member name.   
   >>   
   >> This is assuming offsetof and can deal with general expressions (vs   
   >> just field names).  IIRC, it is only required to work with field names   
   >> (and with plain structs).   
   >   
   > I just read that part of the standard, and it's not clear whether   
   > the second argument to offsetof() has to be a member name or whether   
   > it can be something more elaborate.   
   >   
   > Quoting the N3096 draft of C23, 7.21:   
   >   
   >     offsetof(type, member-designator)   
   >   
   >     which expands to an integer constant expression that has type   
   >     `size_t`, the value of which is the offset in bytes, to the   
   >     subobject (designated by *member-designator*), from the beginning   
   >     of any object of type *type*. The type and member designator   
   >     shall be such that given   
   >   
   >         static type t;   
   >   
   >     then the expression &(t.  *member-designator*) evaluates to   
   >     an address constant.  If the specified *type* defines a new   
   >     type or if the specified member is a bit-field, the behavior   
   >     is undefined.   
   >   
   > The requirements imply that the type can be a struct or a union.   
   >   
   > The term "member designator" is not used elsewhere in the standard.   
   > If the term to be taken literally, then it has to designate a   
   > *member*, not an element of a member.  But the term "subobject",   
   > along with the address constant requirement, could imply that it   
   > could be an arbitrary sequence of members and array elements.   
      
   Clearly the italicized token member-designator is just a placeholder   
   with no semantics implied, and the controlling text here is the word   
   "subobject", which applies recursively.   
      
   Note also that the phrase "from the beginning of any object of type   
   *type*" precludes the use of 'offsetof(S, A[n])', if n is too large,   
   since A[n] will not be a subobject of an arbitrary object of type   
   *type*.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca