This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Alignment of structures.
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Alignment of structures.
- From: Harold Finkbeiner <harold_finkbeiner at stanford dot edu>
- Date: Tue, 30 Nov 1999 23:09:08 -0800
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;
}