Structure Alignment

Structure Alignment

Post by Witman Pen » Tue, 06 Jul 1999 04:00:00



Hi, All

The following is the code to test byte alignment.
-------------------------------------------------
struct m {
char c;
short s;
char c1;

Quote:} m;

main()
{
char a[] = {0x11, 0x22, 0x33, 0x44, 0x55};
struct m *pm = (struct m *)a;
printf("%x %x %x", pm->c, pm->s, pm->c1);
Quote:}

----------------------------------------------
In my opinion, the result should be 0x11 0x3322 0x44. However, the result is
0x11 0x4433, 0x55. I know it's caused by the word alignment. Can anyone
pointer me how to resolve this problem? Thanks in advance.

BR,
Witman Peng

 
 
 

Structure Alignment

Post by Andy Knigh » Tue, 06 Jul 1999 04:00:00



> Hi, All

> The following is the code to test byte alignment.
> -------------------------------------------------
> struct m {
> char c;
> short s;
> char c1;
> } m;
> main()
> {
> char a[] = {0x11, 0x22, 0x33, 0x44, 0x55};
> struct m *pm = (struct m *)a;
> printf("%x %x %x", pm->c, pm->s, pm->c1);
> }
> ----------------------------------------------
> In my opinion, the result should be 0x11 0x3322 0x44. However, the result is
> 0x11 0x4433, 0x55. I know it's caused by the word alignment. Can anyone
> pointer me how to resolve this problem? Thanks in advance.

> BR,
> Witman Peng

Never write C code that makes assumptions about structure member
alignment.

There are tricks that can be performed such as (where supported)...

        #pragma pack(1)

This is available on Microsoft compilers (and probably others) but could
make your code completely non-portable. There's usually a better way but
it rather depends upon what exactly you're hoping to achieve.

--
Andy Knight

You can call me a pedagogue if you like but I won't know what you're on
about!

 
 
 

Structure Alignment

Post by Kenneth C Stah » Tue, 06 Jul 1999 04:00:00


You really shouldn't be writing code like that because it is almost guaranteed
not to be portable. Alignment within a structure is implementation-specific and
it simply is not reasonable in most cases to use a structure in anything except
references to its members. If you ever move to C++ you'll start to understand
why this must be.

Ken


> Hi, All

> The following is the code to test byte alignment.
> -------------------------------------------------
> struct m {
> char c;
> short s;
> char c1;
> } m;
> main()
> {
> char a[] = {0x11, 0x22, 0x33, 0x44, 0x55};
> struct m *pm = (struct m *)a;
> printf("%x %x %x", pm->c, pm->s, pm->c1);
> }
> ----------------------------------------------
> In my opinion, the result should be 0x11 0x3322 0x44. However, the result is
> 0x11 0x4433, 0x55. I know it's caused by the word alignment. Can anyone
> pointer me how to resolve this problem? Thanks in advance.

> BR,
> Witman Peng

 
 
 

Structure Alignment

Post by Dr. Michael Alber » Tue, 06 Jul 1999 04:00:00


Quote:> The following is the code to test byte alignment.
> -------------------------------------------------
> struct m { char c; short s; char c1; } m;
> main() {
> char a[] = {0x11, 0x22, 0x33, 0x44, 0x55};
> struct m *pm = (struct m *)a;
> printf("%x %x %x", pm->c, pm->s, pm->c1); }
> ----------------------------------------------
> In my opinion, the result should be 0x11 0x3322 0x44. However, the result is
> 0x11 0x4433, 0x55. I know it's caused by the word alignment. Can anyone
> pointer me how to resolve this problem? Thanks in advance.

Several folks have pointed out that you should NOT write code
like this.  Under standard C/C++ the behavoir is undefined,
and indeed you will find that the behavoir can and will
change from machine to machine.  Nevertheless, it's worth
understanding what is going on.  

The low level view of your structure, from your results, is

  offset 0:     char c
  offset 1:     unused byte (for alignement)
  offset 2:     address of least significant byte of short s
  offset 3:     address of most signficant byte of short s
  offset 4:     addres of char c1
  offset 5:     unused byte (for alignment)

To see the presence of the 6th byte (at offset 5) print
out the "sizeof(struct m)". You should get "6".  Putting
in this extra byte is neccessary in case later you have
an array of struct m's, in order that the "short" always
be alligned on an even byte offset.

This is all *very* machine dependent (on some machines,
this can also be compiler dependent, altough in C the
layout of struct for most machines is specified in
a document called an Application Binary Interface).  For example,
while many modern machines will add in unused bytes to obtain the
above alignements, some won't, and others might add in
more bytes to force everything to 32-bit or 64-bit alignment.
Further, the fact that the least signficant byte comes first
suggests that you are working with an Intel-based machine.
Most RISC chips would give the opposite order (most signficant
byte first).

Again, you shouldn't rely upon this behavoir, but it is
worth understanding.  In particular, it is worth noting
that if you had defined the

struct m{ char c; char c1; short s };

then on *MANY* machines you would use less space, but
yet you could still write code which would be valid C
on *ALL* machines (assuming you don't do funky things like
at the start of this message :-)).

Best wishes,
 Mike

 
 
 

Structure Alignment

Post by Witman Pen » Wed, 07 Jul 1999 04:00:00


I am porting the protocol stack from 4.4BSD-Lite. Some structure such as IP
have been defined already. When I received a packet, I need to cast it to a
IP header, then when I access the member of the IP header, it will pointer
to the incorrect address. So how to resovlved this problem? Thanks in
advance.

BR,
Witman Peng

Quote:>Several folks have pointed out that you should NOT write code
>like this.  Under standard C/C++ the behavoir is undefined,
>and indeed you will find that the behavoir can and will
>change from machine to machine.  Nevertheless, it's worth
>understanding what is going on.

>The low level view of your structure, from your results, is

>  offset 0:     char c
>  offset 1:     unused byte (for alignement)
>  offset 2:     address of least significant byte of short s
>  offset 3:     address of most signficant byte of short s
>  offset 4:     addres of char c1
>  offset 5:     unused byte (for alignment)

>To see the presence of the 6th byte (at offset 5) print
>out the "sizeof(struct m)". You should get "6".  Putting
>in this extra byte is neccessary in case later you have
>an array of struct m's, in order that the "short" always
>be alligned on an even byte offset.

>This is all *very* machine dependent (on some machines,
>this can also be compiler dependent, altough in C the
>layout of struct for most machines is specified in
>a document called an Application Binary Interface).  For example,
>while many modern machines will add in unused bytes to obtain the
>above alignements, some won't, and others might add in
>more bytes to force everything to 32-bit or 64-bit alignment.
>Further, the fact that the least signficant byte comes first
>suggests that you are working with an Intel-based machine.
>Most RISC chips would give the opposite order (most signficant
>byte first).

>Again, you shouldn't rely upon this behavoir, but it is
>worth understanding.  In particular, it is worth noting
>that if you had defined the

>struct m{ char c; char c1; short s };

>then on *MANY* machines you would use less space, but
>yet you could still write code which would be valid C
>on *ALL* machines (assuming you don't do funky things like
>at the start of this message :-)).

>Best wishes,
> Mike

 
 
 

Structure Alignment

Post by Dr. Michael Alber » Wed, 07 Jul 1999 04:00:00


Quote:> I am porting the protocol stack from 4.4BSD-Lite. Some structure such as IP
> have been defined already. When I received a packet, I need to cast it to a
> IP header, then when I access the member of the IP header, it will pointer
> to the incorrect address. So how to resovlved this problem? Thanks in
> advance.

Implementing services like this often requires an understanding
of low level details like structure alignment.

If memory serves, most of the structures are defined so that
there is really no padding, and you just have to worry about
endian-ness, which can be handled by htons and friends.

See Steven's _TCP/IP_Illustrated_, in particular V.2 which
is a blow-by-blow of the internal stack for BSD-based system.
Also see Steven's _Advanced_Programming_in_the_UNIX_Enviroment_.

Good luck.

Best wishes,
  MIke

 
 
 

1. Hellp on - structure alignment on redhat 5.1 kernel 2.0.35

        Have anyone run into the problem of using the -fpack-struct
flags when compiling and encounter some of the system structures no
longer align properly for access?
        I notice some system structures no longer have the #ifdef in
it to control the padding members as in older versions of RedHat and
this is the cause of my problem. Is it because there is a #pragma or
some other methods to selectively control structure alignment in
potion of code now?
        I realize the default alignment is more efficient, but the
program I am moving over requires to communicate over the network with
another process that have byte aligned data, and there were no ways to
just have a potion of the code the be byte align and the rest default
align.
        Can anyone help me out on this?

Thank You.....

Edward.

2. partner_down - peer holds all free leases

3. Structure Alignment SPARC/Solaris

4. cron emails

5. C structure alignment in Perl

6. Have you seen this - Disk corruption with Sol2.5.1 on Ultra 2?

7. Help - structure alignment

8. ADSL - Connect to BTopenworld BUSINESS service ethernet router.

9. gcc structure alignment

10. Help on - structure alignment in RedHat 5.1 kernel 2.0.35

11. structure alignment (gcc 2.7.2.3 on Linux)

12. Data structure alignment question

13. Structure Alignment