This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: How to stop gcc padding structs???
- To: Grant Edwards <grante at visi dot com>
- Subject: Re: How to stop gcc padding structs???
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Mon, 29 Jan 2001 15:45:42 +0000
- cc: Richard Earnshaw <rearnsha at arm dot com>, gcc at gcc dot gnu dot org, Richard dot Earnshaw at arm dot com
- Organization: ARM Ltd.
- Reply-To: rearnsha at arm dot com
> On Mon, Jan 29, 2001 at 10:26:40AM +0000, Richard Earnshaw wrote:
>
> > > I'm again fighting with gcc trying (and failing) to get it to
> > > stop putting padding bytes into structs. Has anybody figured
> > > out how to prevent gcc from padding structs?
> > >
> > > I ran into this problem before and gave up, finally having to
> > > use hand-calculated constants instead of "sizeof (struct foo)"
> > > in numerous places. For example, it's impossible to define an
> > > Ethernet header structure that ends up having a size of 14
> > > bytes!
> >
> > Relying on sizeof to do this is *very* non-portable.
>
> It's a device driver for a specific board. It doesn't really
> need to be portable.
>
> > Try:
> >
> > typedef struct
> > {
> > volatile unsigned char data;
> > volatile unsigned char _xxx;
> > } __attribute((packed)) high;
>
> Several people suggested that, but it didn't make any
> difference:
>
> ======================================================================
> typedef struct
> {
> volatile unsigned char data __attribute__((packed));
> volatile unsigned char _pad __attribute__((packed));
> } __attribute__((packed)) high __attribute__((packed)) ;
>
> typedef struct
> {
> high a __attribute__((packed));
> high b __attribute__((packed));
> high c __attribute__((packed));
> } __attribute__((packed)) tDemo __attribute__((packed)) ;
>
> tDemo foo;
>
> void *addr[] =
> {
> &foo,
> &foo.a,
> &foo.b,
> &foo.c
> };
>
> int sizeofHigh = sizeof (high);
> ======================================================================
>
> testit: file format elf32-bigarm
> Disassembly of section .data:
>
> 00008000 <addr>:
> 8000: 00008018 andeq r8, r0, r8, lsl r0
> 8004: 00008018 andeq r8, r0, r8, lsl r0
> 8008: 0000801c andeq r8, r0, r12, lsl r0
> 800c: 00008020 andeq r8, r0, r0, lsr #32
>
> 00008010 <sizeofHigh>:
> 8010: 00000004 andeq r0, r0, r4
>
Hmm, it looks to me like you are using a very old compiler (I fixed this
donkeys ages ago -- probably before egcs tree forked).
Here's what I get with current CVS:
@ Generated by gcc 2.97 20010125 (experimental) for ARM/elf
.file "pack.c"
.gcc2_compiled.:
.global addr
.data
.align 2
.type addr,object
.size addr,16
addr:
.word foo
.word foo
.word foo+2
.word foo+4
.global sizeofHigh
.align 2
.type sizeofHigh,object
.size sizeofHigh,4
sizeofHigh:
.word 2
.comm foo, 8 @ 6
BTW splitting the struct declaration from the typedef should still work,
even on the old compiler. hence
struct foo {
char a;
char b;
} __attribute((packed));
typedef struct foo bar;
R.