Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #15762 > unrolled thread
| Started by | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| First post | 2012-01-11 13:31 -0500 |
| Last post | 2012-01-21 11:49 +0000 |
| Articles | 18 — 13 participants |
Back to article view | Back to comp.lang.c
struct alignment "Mark" <mark_cruzNOTFORSPAM@hotmail.com> - 2012-01-11 13:31 -0500
Re: struct alignment Kleuske <kleuske@nowhere.net> - 2012-01-11 19:23 +0000
Re: struct alignment "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2012-01-11 16:58 -0500
Re: struct alignment Ralf Damaschke <rwspam@gmx.de> - 2012-01-11 22:08 +0000
Re: struct alignment Keith Thompson <kst-u@mib.org> - 2012-01-11 14:42 -0800
Re: struct alignment Dr Nick <3-nospam@temporary-address.org.uk> - 2012-01-12 06:56 +0000
Re: struct alignment Ian Collins <ian-news@hotmail.com> - 2012-01-12 20:42 +1300
Re: struct alignment Keith Thompson <kst-u@mib.org> - 2012-01-12 02:20 -0800
Re: struct alignment Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-18 17:03 +0000
Re: struct alignment Kaz Kylheku <kaz@kylheku.com> - 2012-01-18 17:21 +0000
Re: struct alignment jgk@panix.com (Joe keane) - 2012-01-19 21:42 +0000
Re: struct alignment blp@cs.stanford.edu (Ben Pfaff) - 2012-01-19 13:57 -0800
Re: struct alignment Stephen Sprunk <stephen@sprunk.org> - 2012-01-18 11:57 -0600
Re: struct alignment Keith Thompson <kst-u@mib.org> - 2012-01-18 14:28 -0800
Re: struct alignment Robert Wessel <robertwessel2@yahoo.com> - 2012-01-18 13:10 -0600
Re: struct alignment Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-19 11:34 +0000
Re: struct alignment Robert Wessel <robertwessel2@yahoo.com> - 2012-01-19 14:50 -0600
Re: struct alignment Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-21 11:49 +0000
| From | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| Date | 2012-01-11 13:31 -0500 |
| Subject | struct alignment |
| Message-ID | <jekkil$u7v$1@speranza.aioe.org> |
Hello:
#define MAX_SIZE 8
enum my_enum
{
VAL1 = 0;
VAL2,
VAL3,
VAL4,
VAL_MAX
};
struct my_struct
{
enum my_enum e;
int w[MAX_SIZE];
};
Can a layout in such structure cause alignment issues on a target platform?
I understand it much depends on a platform, but generally C compiler is
allowed to do padding of structures, so for example on 32 bit machine, where
'int' is 32 bit long:
struct my_struct
{
int w[MAX_SIZE];
}
is aligned (as fas as I understand) so compiler probably won't be doing
anything else with its layout, but adding 'enum my_enum' in the structure
can poptentially get the structure un-aligned on such machine. Should I be
doing anything special to avoid this and should I be avoiding it at all ?
Would be very thankful for clarifications!
Mark
[toc] | [next] | [standalone]
| From | Kleuske <kleuske@nowhere.net> |
|---|---|
| Date | 2012-01-11 19:23 +0000 |
| Message-ID | <jeknip$vfe$3@dont-email.me> |
| In reply to | #15762 |
On Wed, 11 Jan 2012 13:31:53 -0500, Mark saw fit to publish the following:
> Hello:
>
> #define MAX_SIZE 8
>
> enum my_enum
> {
> VAL1 = 0;
> VAL2,
> VAL3,
> VAL4,
> VAL_MAX
> };
>
> struct my_struct
> {
> enum my_enum e;
> int w[MAX_SIZE];
> };
>
> Can a layout in such structure cause alignment issues on a target
> platform? I understand it much depends on a platform, but generally C
> compiler is allowed to do padding of structures, so for example on 32
> bit machine, where 'int' is 32 bit long:
>
> struct my_struct
> {
> int w[MAX_SIZE];
> }
>
> is aligned (as fas as I understand) so compiler probably won't be doing
> anything else with its layout, but adding 'enum my_enum' in the
> structure can poptentially get the structure un-aligned on such machine.
> Should I be doing anything special to avoid this and should I be
> avoiding it at all ?
>
> Would be very thankful for clarifications!
>
> Mark
In general you should not rely on things being padded or not. Not only can
it differ on different machines, it can differ for different settings of the
same compiler.
Behind the scenes, an enum is treated like an integer and the same issues can
arise. If your code depends on things being padded this or that way or not at
all, start thinking about ways of doing it differently.
--
Schshschshchsch.
-- The Gorn, "Arena", stardate 3046.2
[toc] | [prev] | [next] | [standalone]
| From | "Scott Fluhrer" <sfluhrer@ix.netcom.com> |
|---|---|
| Date | 2012-01-11 16:58 -0500 |
| Message-ID | <1326319096.33357@rcdn-nntpcache-3> |
| In reply to | #15762 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> wrote in message
news:jekkil$u7v$1@speranza.aioe.org...
> Hello:
>
> #define MAX_SIZE 8
>
> enum my_enum
> {
> VAL1 = 0;
> VAL2,
> VAL3,
> VAL4,
> VAL_MAX
> };
>
> struct my_struct
> {
> enum my_enum e;
> int w[MAX_SIZE];
> };
>
> Can a layout in such structure cause alignment issues on a target
> platform?
Nope; it is the compiler's job to make sure that structure elements are
aligned properly (whatever "properly" means for the target platform).
> I understand it much depends on a platform,
Well, yes, the definition of "properly" varies between platforms, and in
addition, compilers sometimes add more padding than strictly required (for
example, because they expect to get a performance benefit out of it)
> but generally C compiler is allowed to do padding of structures,
C compilers are always allowed to add padding to structures (except, of
course, in front of the first element)
> so for example on 32 bit machine, where 'int' is 32 bit long:
>
> struct my_struct
> {
> int w[MAX_SIZE];
> }
>
> is aligned (as fas as I understand) so compiler probably won't be doing
> anything else with its layout, but adding 'enum my_enum' in the structure
> can potentially get the structure un-aligned on such machine.
Nope; the compiler will add padding (if needed) between the structure
members e and w.
> Should I be doing anything special to avoid this and should I be avoiding
> it at all ?
If that structure definition is what you mean, there is absolutely no reason
to avoid it.
--
poncho
[toc] | [prev] | [next] | [standalone]
| From | Ralf Damaschke <rwspam@gmx.de> |
|---|---|
| Date | 2012-01-11 22:08 +0000 |
| Message-ID | <Xns9FD7EB5B21F37dammel@y2plugh.fqdn.th-h.de> |
| In reply to | #15762 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> wrote:
> Can a layout in such structure cause alignment issues on a target
> platform? I understand it much depends on a platform, but generally
> C compiler is allowed to do padding of structures, so for example
> on 32 bit machine, where 'int' is 32 bit long:
>
> struct my_struct
> {
> int w[MAX_SIZE];
> }
>
> is aligned (as fas as I understand) so compiler probably won't
> be doing anything else with its layout, but adding 'enum
> my_enum' in the structure can poptentially get the structure
> un-aligned on such machine. Should I be doing anything special
> to avoid this and should I be avoiding it at all ?
No, you don't need to care. Each structure member will be aligned
according to its own requirements and the whole structure will meet
these requirements, too (as long as esp. for malloc()ed memory the
returned pointer has not been changed "unalignedly" later by the
program).
-- Ralf
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-11 14:42 -0800 |
| Message-ID | <lnipkh3lpg.fsf@nuthaus.mib.org> |
| In reply to | #15762 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> #define MAX_SIZE 8
>
> enum my_enum
> {
> VAL1 = 0;
> VAL2,
> VAL3,
> VAL4,
> VAL_MAX
> };
>
> struct my_struct
> {
> enum my_enum e;
> int w[MAX_SIZE];
> };
>
> Can a layout in such structure cause alignment issues on a target platform?
> I understand it much depends on a platform, but generally C compiler is
> allowed to do padding of structures, so for example on 32 bit machine, where
> 'int' is 32 bit long:
>
> struct my_struct
> {
> int w[MAX_SIZE];
> }
>
> is aligned (as fas as I understand) so compiler probably won't be doing
> anything else with its layout, but adding 'enum my_enum' in the structure
> can poptentially get the structure un-aligned on such machine. Should I be
> doing anything special to avoid this and should I be avoiding it at all ?
The compiler will (in fact, it *must*) insert whatever padding is
necessary so that all the members can be accesssed correctly. It may or
may not insert more padding than it strictly needs to.
The language standard guarantees that the first declared member is at
offset 0, and that all other members are at increasing offsets in the
order in which they're declared (the compiler can't rearrange members).
There can be arbitrary padding between members, or after the last one.
Some compilers have extensions that allow you to request tighter packing
(less padding) than the default. In at least one case, such an
extension can cause serious problems on some platforms; see:
http://stackoverflow.com/questions/8568432/
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628
But if just let the compiler do its job and write portable code (and
don't make assumptions about padding), there shouldn't be any problems.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Dr Nick <3-nospam@temporary-address.org.uk> |
|---|---|
| Date | 2012-01-12 06:56 +0000 |
| Message-ID | <87hb01v279.fsf@temporary-address.org.uk> |
| In reply to | #15770 |
Keith Thompson <kst-u@mib.org> writes: > The compiler will (in fact, it *must*) insert whatever padding is > necessary so that all the members can be accesssed correctly. It may or > may not insert more padding than it strictly needs to. > > The language standard guarantees that the first declared member is at > offset 0, and that all other members are at increasing offsets in the > order in which they're declared (the compiler can't rearrange > members). Does any compiler let you do this? I have done things where the order of a least some elements (usually the first or the last) matters, but it's rare. > There can be arbitrary padding between members, or after the last one. > > Some compilers have extensions that allow you to request tighter packing > (less padding) than the default. I can think of cases where re-arranging could give significant space savings without these risks. In response to the obvious "why don't you do it?" there are a couple of reasons. One, of course, that it will vary from platform to platform. The second is that quite often there is a logical order or partial order of fields from a program logic point of view that is different to the most efficient. For example, you might want to start off with a small integer to say what type of object you have, have a few pointers that point to various type-specific things, then an integer reference count and then a pointer to the next one in a list. Shoving the two integers together could well save you some memory with out the need for the compiler to generate fancy code (as in the "packed" case) but at the loss of program source clarity. -- Online waterways route planner | http://canalplan.eu Plan trips, see photos, check facilities | http://canalplan.org.uk
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-01-12 20:42 +1300 |
| Message-ID | <9n7h6lFvfbU5@mid.individual.net> |
| In reply to | #15777 |
On 01/12/12 07:56 PM, Dr Nick wrote: > Keith Thompson<kst-u@mib.org> writes: > >> The compiler will (in fact, it *must*) insert whatever padding is >> necessary so that all the members can be accesssed correctly. It may or >> may not insert more padding than it strictly needs to. >> >> The language standard guarantees that the first declared member is at >> offset 0, and that all other members are at increasing offsets in the >> order in which they're declared (the compiler can't rearrange >> members). > > Does any compiler let you do this? I have done things where the order > of a least some elements (usually the first or the last) matters, but > it's rare. Let you do what? I didn't see anything optional in Keith's reply. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-12 02:20 -0800 |
| Message-ID | <ln62gh2pes.fsf@nuthaus.mib.org> |
| In reply to | #15778 |
Ian Collins <ian-news@hotmail.com> writes:
> On 01/12/12 07:56 PM, Dr Nick wrote:
>> Keith Thompson<kst-u@mib.org> writes:
>>
>>> The compiler will (in fact, it *must*) insert whatever padding is
>>> necessary so that all the members can be accesssed correctly. It may or
>>> may not insert more padding than it strictly needs to.
>>>
>>> The language standard guarantees that the first declared member is at
>>> offset 0, and that all other members are at increasing offsets in the
>>> order in which they're declared (the compiler can't rearrange
>>> members).
>>
>> Does any compiler let you do this? I have done things where the order
>> of a least some elements (usually the first or the last) matters, but
>> it's rare.
>
> Let you do what? I didn't see anything optional in Keith's reply.
Permit reordering of struct members, I presume. Plenty of C
compilers have plenty of options that break standard compliance.
For that matter, let me back off slightly from my statement above. A
conforming C compiler could provide an implementation-defined #pragma
directive that permits arbitrary reordering of struct members (for size
minimization, for example). C99 6.10.6p1 says that a #pragma directive:
causes the implementation to behave in an implementation-defined
manner. The behavior might cause translation to fail or
cause the translator or the resulting program to behave in a
non-conforming manner.
So a hypothetic implementation might have:
struct reordered {
#pragma REORDER_STRUCT_MEMBERS
char c0;
char c1;
int i;
};
that could put i at offset 0, followed by c0 and c1.
But I've never heard of a C compiler that actually does this.
<OT>I've worked on an Ada compiler that did the equivalent of reordering
struct members, but the Ada standard doesn't require members to be
allocated in declared order.<?OT>
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2012-01-18 17:03 +0000 |
| Message-ID | <slrnjhdurr.1ls.grahn+nntp@frailea.sa.invalid> |
| In reply to | #15781 |
On Thu, 2012-01-12, Keith Thompson wrote:
> Ian Collins <ian-news@hotmail.com> writes:
>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>> Keith Thompson<kst-u@mib.org> writes:
>>>
>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>> necessary so that all the members can be accesssed correctly. It may or
>>>> may not insert more padding than it strictly needs to.
>>>>
>>>> The language standard guarantees that the first declared member is at
>>>> offset 0, and that all other members are at increasing offsets in the
>>>> order in which they're declared (the compiler can't rearrange
>>>> members).
>>>
>>> Does any compiler let you do this? I have done things where the order
>>> of a least some elements (usually the first or the last) matters, but
>>> it's rare.
>>
>> Let you do what? I didn't see anything optional in Keith's reply.
>
> Permit reordering of struct members, I presume. Plenty of C
> compilers have plenty of options that break standard compliance.
But is it really breaking compliance?
struct Foo {
int a;
char b;
int c;
char d;
};
If the compiler lays these out as a-c-b-d, is that really something
which is observable using correct C code?
I seem to recall (but I can be wrong) that the expression
&foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
comparisons inside an array.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-01-18 17:21 +0000 |
| Message-ID | <20120118091128.539@kylheku.com> |
| In reply to | #15910 |
On 2012-01-18, Jorgen Grahn <grahn+nntp@snipabacken.se> wrote:
> On Thu, 2012-01-12, Keith Thompson wrote:
>> Ian Collins <ian-news@hotmail.com> writes:
>>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>>> Keith Thompson<kst-u@mib.org> writes:
>>>>
>>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>>> necessary so that all the members can be accesssed correctly. It may or
>>>>> may not insert more padding than it strictly needs to.
>>>>>
>>>>> The language standard guarantees that the first declared member is at
>>>>> offset 0, and that all other members are at increasing offsets in the
>>>>> order in which they're declared (the compiler can't rearrange
>>>>> members).
>>>>
>>>> Does any compiler let you do this? I have done things where the order
>>>> of a least some elements (usually the first or the last) matters, but
>>>> it's rare.
>>>
>>> Let you do what? I didn't see anything optional in Keith's reply.
>>
>> Permit reordering of struct members, I presume. Plenty of C
>> compilers have plenty of options that break standard compliance.
>
> But is it really breaking compliance?
>
> struct Foo {
> int a;
> char b;
> int c;
> char d;
> };
>
> If the compiler lays these out as a-c-b-d, is that really something
> which is observable using correct C code?
>
> I seem to recall (but I can be wrong) that the expression
> &foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
> comparisons inside an array.
C has an offsetof macro, such that offsetof(struct Foo, a) == 0 has to hold,
and the offsets of the other members have to be in increasing order.
Reordering struct members would break all kinds of code, not all of which is
ISO C mandated.
For instance maintaining backward binary compatibility in shared library
interfaces for structures that are allocated outside of the library
(e.g. in static or automatic storage in client code).
/* Maintainers! Add new members only at the end. */
struct Foo {
int a; /* Lib 1.0 members */
char b;
int c; /* Added in 1.2 */
char d; /* New in 1.3 */
};
In this case, the above struct has to be compatible with the one
compiled in the existing 1.0 clients which is just this:
struct Foo {
int a; /* Lib 1.0 members */
char b;
};
(Knowledge about which type of client is attached to the library can be used to
carefully avoid touching members c and d.)
Sometimes structs are used to conform to an external storage layout,
or hardware registers.
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-01-19 21:42 +0000 |
| Message-ID | <jfa2nj$58j$1@reader1.panix.com> |
| In reply to | #15911 |
In article <20120118091128.539@kylheku.com>,
Kaz Kylheku <kaz@kylheku.com> wrote:
>Reordering struct members would break all kinds of code, not all of which is
>ISO C mandated.
It would be a cool option though...
struct apple
{
char x;
double y;
};
struct vector
{
__rearrangeok
struct apple e[5];
};
->
struct vectorn
{
char exz[5];
double eyz[5];
};
[toc] | [prev] | [next] | [standalone]
| From | blp@cs.stanford.edu (Ben Pfaff) |
|---|---|
| Date | 2012-01-19 13:57 -0800 |
| Message-ID | <87fwfbcq4c.fsf@blp.benpfaff.org> |
| In reply to | #15959 |
jgk@panix.com (Joe keane) writes: > In article <20120118091128.539@kylheku.com>, > Kaz Kylheku <kaz@kylheku.com> wrote: >>Reordering struct members would break all kinds of code, not all of which is >>ISO C mandated. > > It would be a cool option though... C++ has something a little like this. If you write "public:" between each pair of members, then the compiler is allowed to arrange them the members in any order, except that (based on a quick reading, anyway) the first member declared still has to be first. -- "This is a wonderful answer. It's off-topic, it's incorrect, and it doesn't answer the question." --Richard Heathfield
[toc] | [prev] | [next] | [standalone]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2012-01-18 11:57 -0600 |
| Message-ID | <jf716f$e7r$1@dont-email.me> |
| In reply to | #15910 |
On 18-Jan-12 11:03, Jorgen Grahn wrote:
> On Thu, 2012-01-12, Keith Thompson wrote:
>> Ian Collins <ian-news@hotmail.com> writes:
>>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>>> Keith Thompson<kst-u@mib.org> writes:
>>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>>> necessary so that all the members can be accesssed correctly. It may or
>>>>> may not insert more padding than it strictly needs to.
>>>>>
>>>>> The language standard guarantees that the first declared member is at
>>>>> offset 0, and that all other members are at increasing offsets in the
>>>>> order in which they're declared (the compiler can't rearrange
>>>>> members).
>>>>
>>>> Does any compiler let you do this? I have done things where the order
>>>> of a least some elements (usually the first or the last) matters, but
>>>> it's rare.
>>>
>>> Let you do what? I didn't see anything optional in Keith's reply.
>>
>> Permit reordering of struct members, I presume. Plenty of C
>> compilers have plenty of options that break standard compliance.
>
> But is it really breaking compliance?
>
> struct Foo {
> int a;
> char b;
> int c;
> char d;
> };
>
> If the compiler lays these out as a-c-b-d, is that really something
> which is observable using correct C code?
Yes, using offsetof(). And there are plenty of cases where this
actually matters in real-world code.
> I seem to recall (but I can be wrong) that the expression
> &foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
> comparisons inside an array.
It's guaranteed to be meaningful.
N1256, 6.5.8.5:
"If the objects pointed to are members of the same aggregate object,
pointers to structure members declared later compare greater than
pointers to members declared earlier in the structure, ..."
Reordering structure members is therefore a constraint violation, and
any compiler that does it is non-compliant.
S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-18 14:28 -0800 |
| Message-ID | <lnwr8oy7b5.fsf@nuthaus.mib.org> |
| In reply to | #15913 |
Stephen Sprunk <stephen@sprunk.org> writes:
[...]
> Reordering structure members is therefore a constraint violation, and
> any compiler that does it is non-compliant.
A "constraint violation" is an error in code. Errors in compilers are
just bugs.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2012-01-18 13:10 -0600 |
| Message-ID | <sk5eh7t6a2vjfh1f2dtlm1atja5kdrpvg5@4ax.com> |
| In reply to | #15910 |
On 18 Jan 2012 17:03:55 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se>
wrote:
>On Thu, 2012-01-12, Keith Thompson wrote:
>> Ian Collins <ian-news@hotmail.com> writes:
>>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>>> Keith Thompson<kst-u@mib.org> writes:
>>>>
>>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>>> necessary so that all the members can be accesssed correctly. It may or
>>>>> may not insert more padding than it strictly needs to.
>>>>>
>>>>> The language standard guarantees that the first declared member is at
>>>>> offset 0, and that all other members are at increasing offsets in the
>>>>> order in which they're declared (the compiler can't rearrange
>>>>> members).
>>>>
>>>> Does any compiler let you do this? I have done things where the order
>>>> of a least some elements (usually the first or the last) matters, but
>>>> it's rare.
>>>
>>> Let you do what? I didn't see anything optional in Keith's reply.
>>
>> Permit reordering of struct members, I presume. Plenty of C
>> compilers have plenty of options that break standard compliance.
>
>But is it really breaking compliance?
>
> struct Foo {
> int a;
> char b;
> int c;
> char d;
> };
>
>If the compiler lays these out as a-c-b-d, is that really something
>which is observable using correct C code?
>
>I seem to recall (but I can be wrong) that the expression
>&foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
>comparisons inside an array.
Specifically the offsetof()'s of the members of a structure are
defined to be increasing. And 6.2.7.1 (C99) includes:
"(5) As discussed in 6.2.5, a structure is a type consisting of a
sequence of members, whose storage is allocated in an ordered
sequence, and a union..."
It's also required that structures with common leading sections have
the same in-storage layout.
Of course that's all subject to the as-if rule, if the compiler can
determine that the program never looks at the ordering, or the
compiler can fake it, it's allowed to do anything it wants under the
covers, including omitting and reordering parts or all of the
structure.
Of course that all subject to the as-is rule
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2012-01-19 11:34 +0000 |
| Message-ID | <slrnjhfvuh.1ls.grahn+nntp@frailea.sa.invalid> |
| In reply to | #15917 |
On Wed, 2012-01-18, Robert Wessel wrote:
> On 18 Jan 2012 17:03:55 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se>
> wrote:
>
>>On Thu, 2012-01-12, Keith Thompson wrote:
>>> Ian Collins <ian-news@hotmail.com> writes:
>>>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>>>> Keith Thompson<kst-u@mib.org> writes:
>>>>>
>>>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>>>> necessary so that all the members can be accesssed correctly. It may or
>>>>>> may not insert more padding than it strictly needs to.
>>>>>>
>>>>>> The language standard guarantees that the first declared member is at
>>>>>> offset 0, and that all other members are at increasing offsets in the
>>>>>> order in which they're declared (the compiler can't rearrange
>>>>>> members).
>>>>>
>>>>> Does any compiler let you do this? I have done things where the order
>>>>> of a least some elements (usually the first or the last) matters, but
>>>>> it's rare.
>>>>
>>>> Let you do what? I didn't see anything optional in Keith's reply.
>>>
>>> Permit reordering of struct members, I presume. Plenty of C
>>> compilers have plenty of options that break standard compliance.
>>
>>But is it really breaking compliance?
>>
>> struct Foo {
>> int a;
>> char b;
>> int c;
>> char d;
>> };
>>
>>If the compiler lays these out as a-c-b-d, is that really something
>>which is observable using correct C code?
>>
>>I seem to recall (but I can be wrong) that the expression
>>&foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
>>comparisons inside an array.
> It's also required that structures with common leading sections have
> the same in-storage layout.
Ok, that is enough reason for not allowing reordering. To me, the
real reason then seems to be to allow things like the POSIX struct
sockaddr/sockaddr_in/sockaddr_in6/... hack. I always assumed the
sockaddr stuff demanded stronger guarantees from the compiler than the
standard gives.
> Of course that's all subject to the as-if rule, if the compiler can
> determine that the program never looks at the ordering, or the
> compiler can fake it, it's allowed to do anything it wants under the
> covers, including omitting and reordering parts or all of the
> structure.
Yes, but that surely is rare. :-( Most structs are not limited to one
translation unit.
I agree with whoever-it-was upthread: if it was allowed to do it, the
compiler could do a much better layout of my structs than I am willing
to do manually.
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2012-01-19 14:50 -0600 |
| Message-ID | <grvgh75dhleta4o069np41a2m2u3a3hja4@4ax.com> |
| In reply to | #15947 |
On 19 Jan 2012 11:34:43 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se>
wrote:
>On Wed, 2012-01-18, Robert Wessel wrote:
>> On 18 Jan 2012 17:03:55 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se>
>> wrote:
>>
>>>On Thu, 2012-01-12, Keith Thompson wrote:
>>>> Ian Collins <ian-news@hotmail.com> writes:
>>>>> On 01/12/12 07:56 PM, Dr Nick wrote:
>>>>>> Keith Thompson<kst-u@mib.org> writes:
>>>>>>
>>>>>>> The compiler will (in fact, it *must*) insert whatever padding is
>>>>>>> necessary so that all the members can be accesssed correctly. It may or
>>>>>>> may not insert more padding than it strictly needs to.
>>>>>>>
>>>>>>> The language standard guarantees that the first declared member is at
>>>>>>> offset 0, and that all other members are at increasing offsets in the
>>>>>>> order in which they're declared (the compiler can't rearrange
>>>>>>> members).
>>>>>>
>>>>>> Does any compiler let you do this? I have done things where the order
>>>>>> of a least some elements (usually the first or the last) matters, but
>>>>>> it's rare.
>>>>>
>>>>> Let you do what? I didn't see anything optional in Keith's reply.
>>>>
>>>> Permit reordering of struct members, I presume. Plenty of C
>>>> compilers have plenty of options that break standard compliance.
>>>
>>>But is it really breaking compliance?
>>>
>>> struct Foo {
>>> int a;
>>> char b;
>>> int c;
>>> char d;
>>> };
>>>
>>>If the compiler lays these out as a-c-b-d, is that really something
>>>which is observable using correct C code?
>>>
>>>I seem to recall (but I can be wrong) that the expression
>>>&foo.b < &foo.d is not guaranteed to be meaningful, unlike e.g.
>>>comparisons inside an array.
>
>> It's also required that structures with common leading sections have
>> the same in-storage layout.
>
>Ok, that is enough reason for not allowing reordering. To me, the
>real reason then seems to be to allow things like the POSIX struct
>sockaddr/sockaddr_in/sockaddr_in6/... hack. I always assumed the
>sockaddr stuff demanded stronger guarantees from the compiler than the
>standard gives.
>
>> Of course that's all subject to the as-if rule, if the compiler can
>> determine that the program never looks at the ordering, or the
>> compiler can fake it, it's allowed to do anything it wants under the
>> covers, including omitting and reordering parts or all of the
>> structure.
>
>Yes, but that surely is rare. :-( Most structs are not limited to one
>translation unit.
>
>I agree with whoever-it-was upthread: if it was allowed to do it, the
>compiler could do a much better layout of my structs than I am willing
>to do manually.
Perhaps not so rare - a common case occurs when a (small-ish)
structure is passed to or returned from a function that gets inlined.
In C++ you see that in a lot of implicitly generated temporaries. Two
cases in particular I've seen are in some graphics code where a
"point" or "pixel" structure was so treated, and in code with a
"complex" structure for representing, *ahem*, complex numbers. Of
course none of those examples would typically involve any alignment
issues.
In the non-inline case, I agree, it's pretty rare, but is certainly
something that could happen with global optimizations. Consider a
static function that is called (only) from another static function -
the compiler can fairly trivially determine if a structure has any
references that might expose the ordering. LTCG would broaden the
view compiler could take beyond a single translation unit.
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2012-01-21 11:49 +0000 |
| Message-ID | <slrnjhl9hn.1ls.grahn+nntp@frailea.sa.invalid> |
| In reply to | #15958 |
On Thu, 2012-01-19, Robert Wessel wrote: > On 19 Jan 2012 11:34:43 GMT, Jorgen Grahn <grahn+nntp@snipabacken.se> > wrote: > >>On Wed, 2012-01-18, Robert Wessel wrote: ... >>> Of course that's all subject to the as-if rule, if the compiler can >>> determine that the program never looks at the ordering, or the >>> compiler can fake it, it's allowed to do anything it wants under the >>> covers, including omitting and reordering parts or all of the >>> structure. >> >>Yes, but that surely is rare. :-( Most structs are not limited to one >>translation unit. >> >>I agree with whoever-it-was upthread: if it was allowed to do it, the >>compiler could do a much better layout of my structs than I am willing >>to do manually. > Perhaps not so rare - a common case occurs when a (small-ish) > structure is passed to or returned from a function that gets inlined. > In C++ you see that in a lot of implicitly generated temporaries. Two > cases in particular I've seen are in some graphics code where a > "point" or "pixel" structure was so treated, and in code with a > "complex" structure for representing, *ahem*, complex numbers. Of > course none of those examples would typically involve any alignment > issues. True, and that is a case where I assume the compiler does something smart. I automatically assume that in C too, but perhaps that's due to my C++ training. [...] /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web