EmbeddedRelated.com
Forums

Struct alignment problem (GCC)

Started by "ICLI, Bekir (EXT)" April 8, 2008
Hi all,

I am generating my code with GNU-ARM..
I have searched and found that the solution to this struct mis-alignment problem is:
__attribute__((__packed__))

Is there any compiler option, that would do the same for all structs I define?
Or do I have to write this attribute to all of them?
I found in gcc.pdf

-fpack-struct
Pack all structure members together without holes.
Warning: the '-fpack-struct' switch causes GCC to generate code that is
not binary compatible with code generated without that switch. Additionally,
it makes the code suboptimal. Use it to conform to a non-default application
binary interface.
After compiling my code with this option, it did not work, which, I guess, confirms the warning.
I am not even sure if this is the correct compiler option.

Any help would be greatly appreciated..

Mit freundlichem Gru/ Best regards
Bekir ICLI
Foltos wrote:
> Hi,
>
> I think this will not work. Most compilers need the type modifier before
> the variable definition like:
> __packed struct foo {....};
> others need a #pragma on the line before the definition like:
> #pragma packed
> struct foo {...};

Which is why you might do something like this:

for GCC:

#define ATTPACKPRE
#define ATTPACKSUF __attribute__(__packed__))

for others:

#define ATTPACKPRE __packed
#define ATTPACKSUF

And your definition is:

ATTPACKPRE typedef struct {
int intvar;
...
} ATTPACKSUF structname;

Compilers that use #pragma should find another way since you cannot
easily use the c preprocessor to handle a #pragma in a #define....

Ralph
Hi,

I think this will not work. Most compilers need the type modifier before
the variable definition like:
__packed struct foo {....};
others need a #pragma on the line before the definition like:
#pragma packed
struct foo {...};

If you want to get portable code, use 8 bit wide variable arrays, and
macro definitions to access elements. Example:
#define FRAME_LENGTH(fp) (fp[0] | (fp[1]<<8))
#define FRAME_SOMETHING32BIT_LE(fp) (fp[0] | (fp[1]<<8) |
(fp[2]<<16) | (fp[3]<<24) )
uint8_t frame[22];
uint16_t my_data=FRAME_LENGTH(frame);

Foltos

John wrote:
>
> Ditto the STRONG recommendation to avoid the global option.
>
> A while back, I had some compiler issues regarding pointers to packed
> vs. non-packed structures. The fix was to avoid the global option.
> You can do something like:
>
> #define PACKED_STRUCT __attribute__((__packed__))
>
> then you can use
>
> struct SomeStruct {...} PACKED_STRUCT;
>
> This way, if you switch to a different compiler, you re-define the
> PACKED_STRUCT to nothing and get rid of all the compiler warnings (or
> you can redefine it to whatever that particular compiler requires.)
>
> John
>
> --- In A... ,
> "ICLI, Bekir (EXT)"
> wrote:
> >
> > Hi all,
> >
> > I am generating my code with GNU-ARM..
> > I have searched and found that the solution to this struct
> mis-alignment problem is:
> > __attribute__((__packed__))
> >
> > Is there any compiler option, that would do the same for all structs
> I define?
> > Or do I have to write this attribute to all of them?
> > I found in gcc.pdf
> >
> > -fpack-struct
> > Pack all structure members together without holes.
> > Warning: the '-fpack-struct' switch causes GCC to generate code that is
> > not binary compatible with code generated without that switch.
> Additionally,
> > it makes the code suboptimal. Use it to conform to a non-default
> application
> > binary interface.
> > After compiling my code with this option, it did not work, which, I
> guess, confirms the warning.
> > I am not even sure if this is the correct compiler option.
> >
> > Any help would be greatly appreciated..
> >
> > Mit freundlichem Gru/ Best regards
> > Bekir ICLI
> >
Ditto the STRONG recommendation to avoid the global option.

A while back, I had some compiler issues regarding pointers to packed
vs. non-packed structures. The fix was to avoid the global option.
You can do something like:

#define PACKED_STRUCT __attribute__((__packed__))

then you can use

struct SomeStruct {...} PACKED_STRUCT;

This way, if you switch to a different compiler, you re-define the
PACKED_STRUCT to nothing and get rid of all the compiler warnings (or
you can redefine it to whatever that particular compiler requires.)

John

--- In A..., "ICLI, Bekir (EXT)"
wrote:
>
> Hi all,
>
> I am generating my code with GNU-ARM..
> I have searched and found that the solution to this struct
mis-alignment problem is:
> __attribute__((__packed__))
>
> Is there any compiler option, that would do the same for all structs
I define?
> Or do I have to write this attribute to all of them?
> I found in gcc.pdf
>
> -fpack-struct
> Pack all structure members together without holes.
> Warning: the '-fpack-struct' switch causes GCC to generate code that is
> not binary compatible with code generated without that switch.
Additionally,
> it makes the code suboptimal. Use it to conform to a non-default
application
> binary interface.
> After compiling my code with this option, it did not work, which, I
guess, confirms the warning.
> I am not even sure if this is the correct compiler option.
>
> Any help would be greatly appreciated..
>
> Mit freundlichem Gru/ Best regards
> Bekir ICLI
>

Ralph Hempel schrieb:

> Compilers that use #pragma should find another way since you cannot
> easily use the c preprocessor to handle a #pragma in a #define....

Many compiler offer a pre-processor friendly way like __pragma()

--
42Bastian

Note: SPAM-only account, direct mail to bs42@...

Ralph Hempel schrieb:

> 42Bastian wrote:
>> Ralph Hempel schrieb:
>>
>>> Compilers that use #pragma should find another way since you cannot
>>> easily use the c preprocessor to handle a #pragma in a #define....
>> Many compiler offer a pre-processor friendly way like __pragma()
>
> And for those compilers we are indeed grateful :-)

Amen.

--
42Bastian

Note: SPAM-only account, direct mail to bs42@...

Hi,

i was working with a compiler (can't remember the chip and manufacturer)
which needed any special typecast after the type. Like this
static int __packed a;

I know this is really unusual but still I think the only portable
solution is to do it by hand (using macros).

Foltos

Ralph Hempel wrote:
>
> Foltos wrote:
> > Hi,
> >
> > I think this will not work. Most compilers need the type modifier
> before
> > the variable definition like:
> > __packed struct foo {....};
> > others need a #pragma on the line before the definition like:
> > #pragma packed
> > struct foo {...};
>
> Which is why you might do something like this:
>
> for GCC:
>
> #define ATTPACKPRE
> #define ATTPACKSUF __attribute__(__packed__))
>
> for others:
>
> #define ATTPACKPRE __packed
> #define ATTPACKSUF
>
> And your definition is:
>
> ATTPACKPRE typedef struct {
> int intvar;
> ...
> } ATTPACKSUF structname;
>
> Compilers that use #pragma should find another way since you cannot
> easily use the c preprocessor to handle a #pragma in a #define....
>
> Ralph
>
>
42Bastian wrote:
> Ralph Hempel schrieb:
>
>> Compilers that use #pragma should find another way since you cannot
>> easily use the c preprocessor to handle a #pragma in a #define....
>
> Many compiler offer a pre-processor friendly way like __pragma()

And for those compilers we are indeed grateful :-)

Ralph
Foltos wrote:
> Hi,
>
> i was working with a compiler (can't remember the chip and manufacturer)
> which needed any special typecast after the type. Like this
> static int __packed a;
>
> I know this is really unusual but still I think the only portable
> solution is to do it by hand (using macros).

#define ATTPACKPRE __packed
#define ATTPACKSUF

static int ATTPACKPRE a ATTPACKSUF;

Still works and if you switch compilers you just change the macros

Ralph
Hi,

you mean:
ATTPACKPRE static int ATTPACKPRESUF a ATTPACKSUF;

Yeah, looks really nice :)

/Foltos

Ralph Hempel wrote:
>
> Foltos wrote:
> > Hi,
> >
> > i was working with a compiler (can't remember the chip and
> manufacturer)
> > which needed any special typecast after the type. Like this
> > static int __packed a;
> >
> > I know this is really unusual but still I think the only portable
> > solution is to do it by hand (using macros).
>
> #define ATTPACKPRE __packed
> #define ATTPACKSUF
>
> static int ATTPACKPRE a ATTPACKSUF;
>
> Still works and if you switch compilers you just change the macros
>
> Ralph
>
>