Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #162195 > unrolled thread
| Started by | Ian Pilcher <arequipeno@gmail.com> |
|---|---|
| First post | 2021-08-02 12:48 -0500 |
| Last post | 2021-08-04 10:11 -0700 |
| Articles | 9 on this page of 29 — 10 participants |
Back to article view | Back to comp.lang.c
Padding between char array/VLA in struct? Ian Pilcher <arequipeno@gmail.com> - 2021-08-02 12:48 -0500
Re: Padding between char array/VLA in struct? James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-08-02 14:07 -0400
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 11:25 -0700
Re: Padding between char array/VLA in struct? James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-08-02 19:21 -0400
Re: Padding between char array/VLA in struct? Bart <bc@freeuk.com> - 2021-08-02 19:11 +0100
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 11:27 -0700
Re: Padding between char array/VLA in struct? Bart <bc@freeuk.com> - 2021-08-02 20:43 +0100
Re: Padding between char array/VLA in struct? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-08-02 13:11 -0700
Re: Padding between char array/VLA in struct? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-08-02 13:18 -0700
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 13:31 -0700
Re: Padding between char array/VLA in struct? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-08-02 19:50 -0700
Re: Padding between char array/VLA in struct? David Brown <david.brown@hesbynett.no> - 2021-08-04 14:01 +0200
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 13:19 -0700
Re: Padding between char array/VLA in struct? BGB <cr88192@gmail.com> - 2021-08-03 10:40 -0500
Re: Padding between char array/VLA in struct? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-08-03 09:10 -0700
Re: Padding between char array/VLA in struct? BGB <cr88192@gmail.com> - 2021-08-03 12:52 -0500
Re: Padding between char array/VLA in struct? BGB <cr88192@gmail.com> - 2021-08-04 12:05 -0500
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 11:12 -0700
Re: Padding between char array/VLA in struct? Bart <bc@freeuk.com> - 2021-08-02 19:23 +0100
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 13:15 -0700
Re: Padding between char array/VLA in struct? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-08-02 11:32 -0700
Re: Padding between char array/VLA in struct? Ian Pilcher <arequipeno@gmail.com> - 2021-08-02 13:59 -0500
Re: Padding between char array/VLA in struct? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-08-02 12:47 -0700
Re: Padding between char array/VLA in struct? Ian Pilcher <arequipeno@gmail.com> - 2021-08-02 15:27 -0500
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 13:36 -0700
Re: Padding between char array/VLA in struct? antispam@math.uni.wroc.pl - 2021-08-02 21:52 +0000
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-02 13:22 -0700
Re: Padding between char array/VLA in struct? Manfred <noname@add.invalid> - 2021-08-04 17:01 +0200
Re: Padding between char array/VLA in struct? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-08-04 10:11 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-08-02 11:32 -0700 |
| Message-ID | <se9dnc$8a3$1@dont-email.me> |
| In reply to | #162195 |
On 8/2/2021 10:48 AM, Ian Pilcher wrote:
> Given the following:
>
> struct foo {
> /* other members */
> char prefix[PREFIX_SIZE];
> char name[];
> };
>
> Is there any circumstance in which the compiler is permitted to insert
> padding between the 'prefix' and 'name' members?
>
> I'm 99% sure than the answer is no, but I've been unable to track down
> the actual rules anywhere.
>
As far as the formal rules of the language are considered, the compiler
is _always_ permitted to insert padding between struct members (and
after the last member) for whatever reason it pleases. Extra padding can
always be added anywhere, except before the first member of the struct.
So, the answer is "yes".
Also, it is not clear why you mention VLA in the title of your question.
The language does not allow VLA as a struct members. The last member of
your struct is called "flexible array member". This is not VLA and has
nothing to do with VLA.
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Ian Pilcher <arequipeno@gmail.com> |
|---|---|
| Date | 2021-08-02 13:59 -0500 |
| Message-ID | <se9fa1$ikv$1@dont-email.me> |
| In reply to | #162195 |
On 8/2/21 12:48 PM, Ian Pilcher wrote:
> Given the following:
>
> struct foo {
> /* other members */
> char prefix[PREFIX_SIZE];
> char name[];
> };
As has been pointed out, the 'name' member is a flexible array member,
not a variable length array. I apologize for the mistake.
Also, PREFIX_SIZE is intended to represent a macro that expands to a
positive(!) integer constant expression.
The consensus seems to be that no one can think of a good reason that a
compiler would insert padding between the 'prefix' and 'name' members,
but there's nothing in any of the language standards that would forbid
it from doing so. That would certainly explain my failure to find any
such rule.
(_Static_assert here I come!)
Thanks!
--
========================================================================
Ian Pilcher arequipeno@gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-08-02 12:47 -0700 |
| Message-ID | <867dh34oia.fsf@linuxsc.com> |
| In reply to | #162203 |
Ian Pilcher <arequipeno@gmail.com> writes:
> On 8/2/21 12:48 PM, Ian Pilcher wrote:
>
>> Given the following:
>>
>> struct foo {
>> /* other members */
>> char prefix[PREFIX_SIZE];
>> char name[];
>> };
>
> As has been pointed out, the 'name' member is a flexible array member,
> not a variable length array. I apologize for the mistake.
>
> Also, PREFIX_SIZE is intended to represent a macro that expands to a
> positive(!) integer constant expression.
>
> The consensus seems to be that no one can think of a good reason that a
> compiler would insert padding between the 'prefix' and 'name' members,
> but there's nothing in any of the language standards that would forbid
> it from doing so. That would certainly explain my failure to find any
> such rule.
>
> (_Static_assert here I come!)
I am curious to know why you care. Would having a guarantee that
there is no padding affect what code you would write? If it
would then there is a good chance that guarantee-depending code
has undefined behavior somewhere.
[toc] | [prev] | [next] | [standalone]
| From | Ian Pilcher <arequipeno@gmail.com> |
|---|---|
| Date | 2021-08-02 15:27 -0500 |
| Message-ID | <se9kev$ndj$1@dont-email.me> |
| In reply to | #162205 |
On 8/2/21 2:47 PM, Tim Rentsch wrote:
> I am curious to know why you care. Would having a guarantee that
> there is no padding affect what code you would write? If it
> would then there is a good chance that guarantee-depending code
> has undefined behavior somewhere.
It's just a convenient way to refer to either the "full" name (including
the prefix) or the unique part of the name. For example, I've got a
bunch of struct foo's, each of which has a name that starts with "FOO:",
and most of the time I don't care about the prefix.
#define FOO_PREFIX "FOO:"
static const char foo_prefix[sizeof FOO_PREFIX - 1] = FOO_PREFIX;
struct foo {
/* other members */
char prefix[sizeof foo_prefix];
char name[];
}
struct foo *alloc_foo(char *name)
{
struct foo *f;
f = malloc(sizeof *f + strlen(name) + 1);
// Or do something clever with sprintf()
memcpy(&f->prefix, foo_prefix, sizeof foo_prefix);
memcpy(&f->name, name, strlen(name) + 1);
return f;
}
For a given struct foo *f, I can access the full name as f->prefix, and
I can access the unique part as f->name.
--
========================================================================
Ian Pilcher arequipeno@gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-08-02 13:36 -0700 |
| Message-ID | <87k0l38tzd.fsf@nosuchdomain.example.com> |
| In reply to | #162211 |
Ian Pilcher <arequipeno@gmail.com> writes:
> On 8/2/21 2:47 PM, Tim Rentsch wrote:
>> I am curious to know why you care. Would having a guarantee that
>> there is no padding affect what code you would write? If it
>> would then there is a good chance that guarantee-depending code
>> has undefined behavior somewhere.
>
> It's just a convenient way to refer to either the "full" name (including
> the prefix) or the unique part of the name. For example, I've got a
> bunch of struct foo's, each of which has a name that starts with "FOO:",
> and most of the time I don't care about the prefix.
>
> #define FOO_PREFIX "FOO:"
>
> static const char foo_prefix[sizeof FOO_PREFIX - 1] = FOO_PREFIX;
>
> struct foo {
> /* other members */
> char prefix[sizeof foo_prefix];
> char name[];
> }
>
> struct foo *alloc_foo(char *name)
> {
> struct foo *f;
>
> f = malloc(sizeof *f + strlen(name) + 1);
>
> // Or do something clever with sprintf()
> memcpy(&f->prefix, foo_prefix, sizeof foo_prefix);
> memcpy(&f->name, name, strlen(name) + 1);
>
> return f;
> }
>
> For a given struct foo *f, I can access the full name as f->prefix, and
> I can access the unique part as f->name.
Suggestion: Combine `prefix` and `name` into a single array of char, and
use `name+offset` to refer to the portion of the string following the
prefix. Arrays are guaranteed to be contiguous.
If f->name contains a string whose length is at least 4, then f-name and
f->name+4 are both valid pointers to strings.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | antispam@math.uni.wroc.pl |
|---|---|
| Date | 2021-08-02 21:52 +0000 |
| Message-ID | <se9peg$5o4$1@z-news.wcss.wroc.pl> |
| In reply to | #162211 |
Ian Pilcher <arequipeno@gmail.com> wrote:
> On 8/2/21 2:47 PM, Tim Rentsch wrote:
> > I am curious to know why you care. Would having a guarantee that
> > there is no padding affect what code you would write? If it
> > would then there is a good chance that guarantee-depending code
> > has undefined behavior somewhere.
>
> It's just a convenient way to refer to either the "full" name (including
> the prefix) or the unique part of the name. For example, I've got a
> bunch of struct foo's, each of which has a name that starts with "FOO:",
> and most of the time I don't care about the prefix.
>
> #define FOO_PREFIX "FOO:"
>
> static const char foo_prefix[sizeof FOO_PREFIX - 1] = FOO_PREFIX;
>
> struct foo {
> /* other members */
> char prefix[sizeof foo_prefix];
> char name[];
> }
>
> struct foo *alloc_foo(char *name)
> {
> struct foo *f;
>
> f = malloc(sizeof *f + strlen(name) + 1);
>
> // Or do something clever with sprintf()
> memcpy(&f->prefix, foo_prefix, sizeof foo_prefix);
> memcpy(&f->name, name, strlen(name) + 1);
>
> return f;
> }
>
> For a given struct foo *f, I can access the full name as f->prefix,
No, you can not. Going above prefix length is undefined behaviour.
I know no "production" compiler that would detect it, but there
are various debugging aids and some should catch it.
> and
> I can access the unique part as f->name.
--
Waldek Hebisch
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-08-02 13:22 -0700 |
| Message-ID | <87sfzr8umf.fsf@nosuchdomain.example.com> |
| In reply to | #162203 |
Ian Pilcher <arequipeno@gmail.com> writes:
> On 8/2/21 12:48 PM, Ian Pilcher wrote:
>> Given the following:
>> struct foo {
>> /* other members */
>> char prefix[PREFIX_SIZE];
>> char name[];
>> };
>
> As has been pointed out, the 'name' member is a flexible array member,
> not a variable length array. I apologize for the mistake.
>
> Also, PREFIX_SIZE is intended to represent a macro that expands to a
> positive(!) integer constant expression.
>
> The consensus seems to be that no one can think of a good reason that a
> compiler would insert padding between the 'prefix' and 'name' members,
> but there's nothing in any of the language standards that would forbid
> it from doing so. That would certainly explain my failure to find any
> such rule.
>
> (_Static_assert here I come!)
The ABI for whatever target platform you're interested in might have
something to say about it.
(I can imagine that some compiler might find it convenient to give the
name[] member an alignment stricter than 1 byte.)
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-08-04 17:01 +0200 |
| Message-ID | <seea3q$7a6$1@gioia.aioe.org> |
| In reply to | #162210 |
On 8/2/2021 10:22 PM, Keith Thompson wrote:
> Ian Pilcher <arequipeno@gmail.com> writes:
>> On 8/2/21 12:48 PM, Ian Pilcher wrote:
>>> Given the following:
>>> struct foo {
>>> /* other members */
>>> char prefix[PREFIX_SIZE];
>>> char name[];
>>> };
>>
>> As has been pointed out, the 'name' member is a flexible array member,
>> not a variable length array. I apologize for the mistake.
>>
>> Also, PREFIX_SIZE is intended to represent a macro that expands to a
>> positive(!) integer constant expression.
>>
>> The consensus seems to be that no one can think of a good reason that a
>> compiler would insert padding between the 'prefix' and 'name' members,
>> but there's nothing in any of the language standards that would forbid
>> it from doing so. That would certainly explain my failure to find any
>> such rule.
>>
>> (_Static_assert here I come!)
>
> The ABI for whatever target platform you're interested in might have
> something to say about it.
It may be worth pointing out that ABIs set requirements for exported
interfaces - they don't pose restrictions to compilers for accesses to
local data and functions.
>
> (I can imagine that some compiler might find it convenient to give the
> name[] member an alignment stricter than 1 byte.)
>
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-08-04 10:11 -0700 |
| Message-ID | <87fsvp879i.fsf@nosuchdomain.example.com> |
| In reply to | #162227 |
Manfred <noname@add.invalid> writes:
> On 8/2/2021 10:22 PM, Keith Thompson wrote:
>> Ian Pilcher <arequipeno@gmail.com> writes:
>>> On 8/2/21 12:48 PM, Ian Pilcher wrote:
>>>> Given the following:
>>>> struct foo {
>>>> /* other members */
>>>> char prefix[PREFIX_SIZE];
>>>> char name[];
>>>> };
>>>
>>> As has been pointed out, the 'name' member is a flexible array member,
>>> not a variable length array. I apologize for the mistake.
>>>
>>> Also, PREFIX_SIZE is intended to represent a macro that expands to a
>>> positive(!) integer constant expression.
>>>
>>> The consensus seems to be that no one can think of a good reason that a
>>> compiler would insert padding between the 'prefix' and 'name' members,
>>> but there's nothing in any of the language standards that would forbid
>>> it from doing so. That would certainly explain my failure to find any
>>> such rule.
>>>
>>> (_Static_assert here I come!)
>> The ABI for whatever target platform you're interested in might have
>> something to say about it.
>
> It may be worth pointing out that ABIs set requirements for exported
> interfaces - they don't pose restrictions to compilers for accesses to
> local data and functions.
Sure, but it would be bizarre to use the ABI-imposed layout for struct foo
if it's exported, but a different layout if it isn't.
>> (I can imagine that some compiler might find it convenient to give
>> the
>> name[] member an alignment stricter than 1 byte.)
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web