This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 8/29/19 1:17 PM, Carlos O'Donell wrote:
On 8/29/19 2:36 PM, Martin Sebor wrote:On 8/29/19 11:54 AM, Carlos O'Donell wrote:On 8/29/19 1:28 PM, Martin Sebor wrote:A longer term solution is to replace the array with a suitably aligned char buffer and write the data into it, e.g., like this: union { struct charseq replace[2]; char buf[sizeof (struct charseq) * 2]; } u; u.replace[0].nbytes = 1; const char s[] = "?"; memcpy (u.buf + offsetof (struct charseq, bytes), "?", 2); This is still iffy but it won't trigger an out-of-bounds warning. This code should still be flagged for the declaration of an object with an internal zero-length array, so that will need to be dealt with when such a warning is introduced (e.g., by suppressing the warning).Why is this iffy? This is the kind of solution I was thinking of using. The alternative is an entirely new type that has a non-zero-length array that can be used for static object allocation like this, but then you need to cast between them in a safe way?It's iffy because of the interior zero-length array. GCC accepts zero-length array members anywhere but it doesn't always avoid assuming their elements don't overlap other members. Some other compilers don't allow zero-length arrays in definitions where they're followed by another member or element of a larger array. I'd like to see GCC warn for such uses because of the overlapping problem. Martin PS For example, GCC folds the test below to false. Clang does the same with slightly different test cases. struct charseq replace[2]; void f (int i) { int x = *replace[1].name; replace[0].bytes[i] = 0; if (x != *replace[1].name) __builtin_abort (); }This static allocation is rare, it's the only one. Is there a viable solution for a static allocation of a structure that ends in a VLA?
The static allocation isn't necessarily a problem. Defining arrays or members of structures with flexible array members (or zero-length arrays) in a way that allows overlapping is. The only viable alternative I can think of is to define replace as a char buffer: static _Alignas (struct charseq) unsigned char replace[sizeof (struct charseq[2])]; memcpy (replace + offsetof (struct charseq, nbytes), (int[]){ 1 }, sizeof (int)); memcpy (replace + offsetof (struct charseq, bytes), "?", 2); This isn't pretty but it's close to strictly conforming. The only non-conforming part other than the zero-length member is that (if) the char array is later accessed as struct charseq. But that's so pervasive that it might as well be in the standard. Martin
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |