Need clarity on structure alignment

S

syuga2012

Hi Folks,

I came across that structure elements should be aligned on even
boundary or multiples of 4. Does this mean that if a structure has 3
members as follows

struct a
{
char c;
int i;
long t;

};

the int would have to be aligned to a even memory address and the long
to a memory address which is a multiple of 4.
What about the char? Can it be on a even or odd memory address?

What if there was another char in between i and t? Will there be any
padding and will char be on even memory address or odd memory address?
How many bytes padding will be added between i and t. I am really
confused about this whole alignment thing. I did a google but I am
more confused after that! Also does this alignment apply only to
structures or its a general rule. Sorry, If I am sounding silly, but I
am not at peace.Can some one be kind enough to explain me in simple
terms?
Thank you very much for your time. Appreciate it.
syuga
 
F

Fred

Hi Folks,

I came across that structure elements should be aligned on even
boundary or multiples of 4. Does this mean that if a structure has 3
members as follows

struct a
{
 char c;
 int i;
 long t;

};

the int would have to be aligned to a even memory address and the long
to a memory address which is a multiple of 4.
What about the char? Can it be on a even or odd memory address?

What if there was another char in between i and t? Will there be any
padding and will char be on even memory address or odd memory address?
How many bytes padding will be added between i and t. I am really
confused about this whole alignment thing. I did a google but I am
more confused after that! Also does this alignment apply only to
structures or its a general rule. Sorry, If I am sounding silly, but I
am not at peace.Can some one be kind enough to explain me in simple
terms?
Thank you very much for your time. Appreciate it.

Why do you care about alignment issues?

Unless you are going to write a compiler, there is probably no reason
for
you to care about alignment at all. The compiler you use will do it
correctly - that's usually all you really need to know.
 
B

Bartc

Why do you care about alignment issues?

Unless you are going to write a compiler, there is probably no reason
for
you to care about alignment at all. The compiler you use will do it
correctly - that's usually all you really need to know.

There are any number of reasons why someone would like to know exactly how a
struct is arranged. For example, to minimise the size of a struct; one of
the following uses 50% more space on my machine:

struct st {
char a;
int i;
char b;
int j;
char c;
int k;
};

struct st2 {
int i;
int j;
int k;
char a;
char b;
char c;
};

To the OP: it's easy enough to experiment with different struct contents and
look at the sizes, addresses and offsets produced. (The results will vary
according to the compiler and target.) There should also be some way of
turning off padding completely.
 
K

Keith Thompson

Hi Folks,

I came across that structure elements should be aligned on even
boundary or multiples of 4. Does this mean that if a structure has 3
members as follows

struct a
{
char c;
int i;
long t;

};

the int would have to be aligned to a even memory address and the long
to a memory address which is a multiple of 4.
What about the char? Can it be on a even or odd memory address?

Maybe.

Alignment requirements for different types vary depending on the
underlying hardware, and on what the compiler chooses to enforce.
*If* int requires 2-byte alignment, then it's guaranteed that c will
be at an offset of 0 and i will be at an even offset of at least 2
(most likely exactly 2, but the compiler can choose to insert more
padding if it feels like it). Struct members must be allocated in
their declared order (I'm ignoring bit fields), and the compiler may
insert arbitrary padding between any two members or at the end.

You're likely to save some space by putting larger members first and
similar members together, but in most cases it's better just to let
the compiler worry about it for you -- unless you need to match some
externally imposed layout, in which case an ordinary struct
declaration won't guarantee that you get the results you need.

Incidentally, on many systems int and long are the same size. The
only guarantees for int and long are that int is at least 16 bits,
long is at least 32 bits, and long is at least as wide as int.
 
E

Eric Sosman

Bartc said:
[...]
To the OP: it's easy enough to experiment with different struct contents
and look at the sizes, addresses and offsets produced. (The results will
vary according to the compiler and target.) There should also be some
way of turning off padding completely.

s/should/may/
s/way/non-portable way/

.... and if there is, it will probably incur a speed penalty
and is likely to incur a code size penalty.
 
A

Andrew Smallshaw

The compiler puts padding for alignment where it wants to.

Correct. The ANSI standard makes absolutely no guarantees about
alignment. I am reminded of a particular message that I always
find incredibly annoying whenever I see it:

This is xine (X11 gui) - a free video player v0.99.5.
(c) 2000-2007 The xine Team.
Compiler did not align stack variables. Libavcodec has been miscompiled
and may be very slow or crash. This is not a bug in libavcodec,
but in the compiler. Do not report crashes to FFmpeg developers.

I read this as:

Compiler did not align stack variables. We know much better than
you, the compiler author, or the ISO standardisation committee. Do
not report crashes to FFmpeg developers since we have absolutely no
interest in writing solid, reliable and standards-conforming code.
 
E

Eric Sosman

Andrew said:
Correct. The ANSI standard makes absolutely no guarantees about
alignment.

"Absolutely" is absolutely too strong. For example,
the Standard guarantees that "alignment" is a divisibility
criterion, and that the alignment divisor for a type is also
a divisor of the type's size. The Standard also guarantees
that memory obtained from malloc() et al. is properly aligned
for any data type whatsoever, a guarantee without which it's
hard to see how one could use malloc() effectively.
I am reminded of a particular message that I always
find incredibly annoying whenever I see it:

This is xine (X11 gui) - a free video player v0.99.5.
(c) 2000-2007 The xine Team.
Compiler did not align stack variables. Libavcodec has been miscompiled
and may be very slow or crash. This is not a bug in libavcodec,
but in the compiler. Do not report crashes to FFmpeg developers.

I read this as:

Compiler did not align stack variables. We know much better than
you, the compiler author, or the ISO standardisation committee. Do
not report crashes to FFmpeg developers since we have absolutely no
interest in writing solid, reliable and standards-conforming code.

There's that word "absolutely" again, and with all the
absolute certainty of the earlier use ..
 
A

Antoninus Twink

Compiler did not align stack variables. Libavcodec has been miscompiled
and may be very slow or crash. This is not a bug in libavcodec,
but in the compiler. Do not report crashes to FFmpeg developers.

I read this as:

Compiler did not align stack variables. We know much better than
you, the compiler author, or the ISO standardisation committee. Do
not report crashes to FFmpeg developers since we have absolutely no
interest in writing solid, reliable and standards-conforming code.

This is perhaps the most preposterously idiotic statement I've ever read
on clc that wasn't written by Richard Heath Field.

libavcodec is a library for encoding and decoding video files. This is
computationally intensive and performance-critical: would you be happy
to find that your favorite porno kept stopping and stuttering because
the decoding routine had been written to be clc-conforming,
ISO-adhering, 100%-portable?

Of course not! This is a good example where every optimization trick -
platform specific, even compiler specific - is fully justified. If you
really find this such a distasteful insult to the great gods of ISO, you
should stick to clc-approved programs like getline() clones, and above
all avoid any real-world programming jobs.
 
K

Kenny McCormack

This is perhaps the most preposterously idiotic statement I've ever read
on clc that wasn't written by Richard Heath Field.

True. But it is, in fact, required, by the rules of CLC.
To repeat, this is the only possible position that can be taken here,
and stay on the right side of the "regs".

This shows just how out of touch CLC is.
 
A

Andrew Smallshaw

libavcodec is a library for encoding and decoding video files. This is
computationally intensive and performance-critical: would you be happy
to find that your favorite porno kept stopping and stuttering because
the decoding routine had been written to be clc-conforming,
ISO-adhering, 100%-portable?

That is fair enough, but that is not what they are doing. They
are claiming that the compiler is _buggy_ when it is following
behaviour allowed by the standard. That is passing off their
problem onto somebody else.
 
N

Nate Eldredge

Andrew Smallshaw said:
That is fair enough, but that is not what they are doing. They
are claiming that the compiler is _buggy_ when it is following
behaviour allowed by the standard. That is passing off their
problem onto somebody else.

There are many cases in which gcc promises (explicitly or implicitly)
behavior above and beyond what's required by the C standard. For
example, my platform has an ABI that guarantees that sizeof(int) == 4.
If, on my computer, gcc said that sizeof(int)==7, I would rightly say
that gcc was buggy, even though the standard allows this behavior.

Likewise, if the following code wasn't compiled by gcc:

const char *how_big(int a) {
switch (a) {
case 1 ... 7 : return "SMALL";
case 11 ... 18 : return "MEDIUM";
case 21 ... 30 : return "LARGE";
default: return "UNKNOWN";
}
}

I would again say that gcc was buggy. It's syntactically incorrect
standard C, but makes use of a documented GCC extension. (Off the
subject, I tested this, and the code generated by gcc 4.2.1 on amd64,
using -O2, is rather ingenious. If anyone can guess its approach, I'll
be impressed.)

Moreover, I can't think of a good way for a (non-portable) C program to
align the stack itself if the compiler/library does not take care of it.
(Can you?) So I don't see it as passing their problem off to someone
else, when it's not one that they can effectively solve without
implementation help.
 
T

Tony

Hi Folks,

I came across that structure elements should be aligned on even
boundary or multiples of 4. Does this mean that if a structure has 3
members as follows

struct a
{
char c;
int i;
long t;

};

the int would have to be aligned to a even memory address and the long
to a memory address which is a multiple of 4.
What about the char? Can it be on a even or odd memory address?

What if there was another char in between i and t? Will there be any
padding and will char be on even memory address or odd memory address?
How many bytes padding will be added between i and t. I am really
confused about this whole alignment thing. I did a google but I am
more confused after that! Also does this alignment apply only to
structures or its a general rule. Sorry, If I am sounding silly, but I
am not at peace.Can some one be kind enough to explain me in simple
terms?
Thank you very much for your time. Appreciate it.

"Why do you care about alignment issues?"

Maybe he's writing a memory manager. Maybe he's doing high-performance
reading/writing of structs (rather than marshaling). Indeed though, if he's
asking those questions he doesn't know how and where those things can be
controlled and it will be awhile before his software will work (and unknown
on how many platforms it will compile the same way on).

Tony
 
T

Tony

Eric Sosman said:
Bartc said:
[...]
To the OP: it's easy enough to experiment with different struct contents
and look at the sizes, addresses and offsets produced. (The results will
vary according to the compiler and target.) There should also be some way
of turning off padding completely.

s/should/may/
s/way/non-portable way/

... and if there is, it will probably incur a speed penalty
and is likely to incur a code size penalty.

Maybe his code need not be portable beyond his development platform. Maybe
space and time efficiency is not important.

Tony
 
T

Tony

Keith Thompson said:
Maybe.

Alignment requirements for different types vary depending on the
underlying hardware, and on what the compiler chooses to enforce.

I remember seeing something that left me with the impression that C (C++?)
guarantees that a struct will be aligned on a pointer-size boundary (using
the std mem mgr). (?) Something about 4-byte struct alignment (on a 32-bit
machine no doubt) sticks in my mind.

Tony
 
T

Tony

The compiler puts padding for alignment where it wants to.

Unless you tell it specifically how to do padding/alignment. Whether #pragma
pack(1) will get you padding at the end of a struct or not is probably iffy.
Personally, I try to write structs that align nicely naturally without
padding. I wouldn't use just one 8-bit integer in a struct on a 32-bit
machine: I'd use 4 consequetive ones making the struct a multiple of 4
bytes.

Tony
 
T

Tony

Andrew Smallshaw said:
Correct. The ANSI standard makes absolutely no guarantees about
alignment.

Little software can be created with just the standard. All else is written
to one or more platforms. I suspect that most compilers offer some level of
alignment control (they do on Wintel).

Tony
 
T

Tony

Kenny McCormack said:
True. But it is, in fact, required, by the rules of CLC.
To repeat, this is the only possible position that can be taken here,
and stay on the right side of the "regs".

This shows just how out of touch CLC is.

Or how bare-boned C is as a programming language: to be "close to the
hardware" it loses a lot of practicalness ("C: for compiler implementors
only"?).

Tony
 
J

James Kuyper

Tony wrote:
....
I remember seeing something that left me with the impression that C (C++?)
guarantees that a struct will be aligned on a pointer-size boundary (using
the std mem mgr). (?) Something about 4-byte struct alignment (on a 32-bit
machine no doubt) sticks in my mind.

There is no such requirement. 6.2.5p11 says "All pointers to structure
types shall have the same representation and alignment requirements
as each other." However, that applies to the struct pointers, not to the
structs themselves.
 
J

James Kuyper

Tony said:
Little software can be created with just the standard. All else is written
to one or more platforms. I suspect that most compilers offer some level of
alignment control (they do on Wintel).

Precisely: the compiler imposes those requirements, not the standard.
Code that is not intended to be portable can be written to rely upon a
knowledge of how alignment restrictions work on a particular
implementation. Portable code should be written to work correctly no
matter what the alignment restrictions are.
 
G

Guest

Maybe his code need not be portable beyond his development platform. Maybe
space and time efficiency is not important.

if he doesn't care about either space or time why is he pissing
about with padding? Just write simple code and ship it.

Often people get sucked into worrying about "efficiency" without
really understanding why or even *what* it is.

efficiency = achieving a desired task within constraints
significant to the task

and often the "significant" bit is ignored
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

structure alignment rules 4
Alignment problems 20
Alignment of a structure. 6
struct alignment 14
malloc and alignment question 8
gcc alignment options 19
determining alignment of objects 5
Alignment, Cast 27

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top