This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Alignment of structures.


I hope I can explain this properly.

If I add in an extra long into a struct definition the structures are not
packed together, rather they are put on 32 byte boundary.  This seems to 
be a bug in the Intel alignment.  I tried to trim this down to a very small example.

I have included two examples test_bad.c and test_good.c each of which
was compiled with gcc 2.95.2 on a linux system.

gcc -g -o test_bad test_bad.c
gcc -g -o test_good test_good.c

There are three static structures (sckw01, sckw59, sckw65) which look
like this in test_good.c.  The size of each structure is 32 bytes.

(gdb) x/24x p
0x8049520 <sckw01>:     0x00004649      0x00000000      0x00000000      0x00000000
0x8049530 <sckw01+16>:  0x02010002      0x06050403      0x000000ff      0x0804842c
0x8049540 <sckw59>:     0x00544553      0x00000000      0x00000000      0x00000000
0x8049550 <sckw59+16>:  0x02010003      0x06050403      0x000000ff      0x0804842c
0x8049560 <sckw65>:     0x574f4853      0x00000000      0x00000000      0x00000000
0x8049570 <sckw65+16>:  0x02010004      0x06050403      0x000000ff      0x0804842c
(gdb) 

If I add another long in the structure the size of the structure is 36 bytes
but there is now a seperation of 64 bytes between structures.

(gdb) x/40x p
0x8049520 <sckw01>:     0x00004649      0x00000000      0x00000000      0x00000000
0x8049530 <sckw01+16>:  0x02010002      0x06050403      0x000000ff      0x00000fff
0x8049540 <sckw01+32>:  0x0804842c      0x00000000      0x00000000      0x00000000
0x8049550 <sckw01+48>:  0x00000000      0x00000000      0x00000000      0x00000000
0x8049560 <sckw59>:     0x00544553      0x00000000      0x00000000      0x00000000
0x8049570 <sckw59+16>:  0x02010003      0x06050403      0x000000ff      0x00000fff
0x8049580 <sckw59+32>:  0x0804842c      0x00000000      0x00000000      0x00000000
0x8049590 <sckw59+48>:  0x00000000      0x00000000      0x00000000      0x00000000
0x80495a0 <sckw65>:     0x574f4853      0x00000000      0x00000000      0x00000000
0x80495b0 <sckw65+16>:  0x02010004      0x06050403      0x000000ff      0x00000fff

This does not make sense to me.  It seems to me they should be packed together 
like the previous example.  Infact they are when I compile it with gcc 2.95.1 on
a Solaris system.

If you run the programs they print out the size of the structures and the distance
between the structures.

[hrf@theme wylbur]$ ./test_good
sizeof NKW struct = 32
distance between structs = 32
[hrf@theme wylbur]$ ./test_bad
sizeof NKW struct = 36
distance between structs = 64

The same programs compiled on Solaris produce 

lindy:~> ./test_good
sizeof NKW struct = 32
distance between structs = 32
lindy:~> ./test_bad 
sizeof NKW struct = 36
distance between structs = 36

which is what I would expect.

Thanks and let me know if I can clarify anything.
  -Harold

PS: I downloaded a fresh copy of gcc and configured it as follow

./configure --prefix=/usr/local --enable-shared --enable-threads

    and here is the start of the gcc -v --help output 

[hrf@theme wylbur]$ gcc -v --help 2>&1  | more
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
gcc version 2.95.2 19991024 (release)

 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cpp -lang-c -v -D__GNUC__=2 -D_
_GNUC_MINOR__=95 -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i3
86__ -D__linux__ -D__unix -D__linux -Asystem(posix) -Acpu(i386) -Amachine(i386) 
-Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__ -D__pentiumpr
o -D__pentiumpro__ --help help-dummy /tmp/ccFLbw2C.i
GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)


-- 
 _____                                                            _____
( ___ )----------------------------------------------------------( ___ )
 | / | Harold Finkbeiner    Email: harold_finkbeiner@stanford.edu | \ |
 | / | Stanford University  Phone: (650) 725-3353                 | \ |
 | / |                                                            | \ |
 |___|            #include <standard.disclaimer.h>                |___|
(_____)----------------------------------------------------------(_____)



#include <stdio.h>

void MTOKEN();

typedef struct nkw
   {
      char tok[16];                /* TOKEN, BLANK PADDED */
      short tokl;                  /* TOKEN LENGTH */
      unsigned char flg1;          /* FIELD FLAGS */
      unsigned char flg2;          /* MISC FLAGS */
      unsigned char flg3;          /* MATCH SPECS,SPECIAL ACTIONS */
      unsigned char flg4;          /* INTEGER MATCH SPECS */
      unsigned char flg5;
      unsigned char flg6;

      long parm1;                  /* MATCH PARM 1 */
/*      long parm2;   */               /* MATCH PARM 2 */
      void (*mat)();
   } NKW;

static NKW sckw01 = { "IF",2,1,2,3,4,5,6,255,MTOKEN };
static NKW sckw59 = { "SET",3,1,2,3,4,5,6,255,MTOKEN };
static NKW sckw65 = { "SHOW",4,1,2,3,4,5,6,255,MTOKEN };

main ()
{
        int s;
	char *p = (char *) &sckw01;

        s = sizeof(sckw01);

        printf("sizeof NKW struct = %d\n", s);
        printf("distance between structs = %u\n", ((unsigned long)&sckw59)-((unsigned long)&sckw01));
}

void MTOKEN()
{
    return;
}


#include <stdio.h>

void MTOKEN();

typedef struct nkw
   {
      char tok[16];                /* TOKEN, BLANK PADDED */
      short tokl;                  /* TOKEN LENGTH */
      unsigned char flg1;          /* FIELD FLAGS */
      unsigned char flg2;          /* MISC FLAGS */
      unsigned char flg3;          /* MATCH SPECS,SPECIAL ACTIONS */
      unsigned char flg4;          /* INTEGER MATCH SPECS */
      unsigned char flg5;
      unsigned char flg6;

      long parm1;                  /* MATCH PARM 1 */
      long parm2;                  /* MATCH PARM 2 */
      void (*mat)();
   } NKW;

static NKW sckw01 = { "IF",2,1,2,3,4,5,6,255,4095,MTOKEN };
static NKW sckw59 = { "SET",3,1,2,3,4,5,6,255,4095,MTOKEN };
static NKW sckw65 = { "SHOW",4,1,2,3,4,5,6,255,4095,MTOKEN };

main ()
{
        int s;
	char *p = (char *) &sckw01;

        s = sizeof(sckw01);

        printf("sizeof NKW struct = %d\n", s);
        printf("distance between structs = %u\n", ((unsigned long)&sckw59)-((unsigned long)&sckw01));
}

void MTOKEN()
{
    return;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]