Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GCC alternative to #pragma pack

0 views
Skip to first unread message

Dan Becker

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
Hello,

I am a new user of Linux and Gcc. I am porting a C++/C project that
typically is compiled with IBM VisualAge C++ compiler and is littered
with #pragma pack directives to control the alignment of structures
(e.g. #pragma pack(8) or #pragma pack(4)). The GCC compiler is giving a
warning on these pragmas, namely:
path/filename:645: warning: malformed '#pragma pack'

Is there a GCC compiler switch equivalent to pragma pack? Is there a way
to turn this warning off?

I looked in the man gcc page and the LDP site but could find nothing.

--
Thanks, Dan
E-mail: beck...@NOSPAM.io.com
Web: http://www.io.com/~beckerdo

Grant Edwards

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
In article <38B6B5DC...@NOSPAM.io.com>, Dan Becker wrote:

>I am a new user of Linux and Gcc. I am porting a C++/C project that
>typically is compiled with IBM VisualAge C++ compiler and is littered
>with #pragma pack directives to control the alignment of structures
>(e.g. #pragma pack(8) or #pragma pack(4)). The GCC compiler is giving a
>warning on these pragmas, namely:
> path/filename:645: warning: malformed '#pragma pack'
>
>Is there a GCC compiler switch equivalent to pragma pack? Is there a way
>to turn this warning off?
>
>I looked in the man gcc page and the LDP site but could find nothing.

You need to use __attribute__((packed)) like this:

struct
{
char a[3] __attribute__((packed));
char b[1] __attribute__((packed));
}foo;

Warning: while this will make sure that there are no empty
spaced _between_ fields, it is not possible, AFAICT, to make
sure there is no empty space at the end of the struct. E.g.
there might not be any empty space before a or between a and b,
but sizeof foo might be greater than 4.

--
Grant Edwards grante Yow! What GOOD is a
at CARDBOARD suitcase ANYWAY?
visi.com

Norm Dresner

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
I'm using gcc-2.7.2.3-14 in a RedHat 5.2 system and this compiler happily
takes packing pragmas in the form
#pragma pack(1) // align to 1-byte boundary, essentially no
packing
#pragma pack(2) // align to short (2-byte) boundary
#pragma pack(4)
#pragma pack(8)

and
#pragma pack() // restore default

I can't imagine what your compiler is objecting to based on the little code
you posted.

Norm

Dan Becker <beck...@NOSPAM.io.com> wrote in message
news:38B6B5DC...@NOSPAM.io.com...
> Hello,


>
> I am a new user of Linux and Gcc. I am porting a C++/C project that
> typically is compiled with IBM VisualAge C++ compiler and is littered
> with #pragma pack directives to control the alignment of structures
> (e.g. #pragma pack(8) or #pragma pack(4)). The GCC compiler is giving a
> warning on these pragmas, namely:
> path/filename:645: warning: malformed '#pragma pack'
>
> Is there a GCC compiler switch equivalent to pragma pack? Is there a way
> to turn this warning off?
>
> I looked in the man gcc page and the LDP site but could find nothing.
>

Mumit Khan

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
In article <%AAt4.5274$YG.3...@bgtnsc04-news.ops.worldnet.att.net>,

Norm Dresner <nd...@att.net> wrote:
>I'm using gcc-2.7.2.3-14 in a RedHat 5.2 system and this compiler happily
>takes packing pragmas in the form
>#pragma pack(1) // align to 1-byte boundary, essentially no
>packing
>#pragma pack(2) // align to short (2-byte) boundary
>#pragma pack(4)
>#pragma pack(8)
>
>and
>#pragma pack() // restore default
>
>I can't imagine what your compiler is objecting to based on the little code
>you posted.

It may be accepting the code, but the code produced is certainly not
correct. Since you're on a Linux, the effect is not a problem since it's
self consistent. The pragma packing code went through a rewrite and now
in the gcc mainline (next major release is gcc-2.96). I've produced
patches for gcc-2.95.x releases.

Someone else mentioned using __attribute__((packed)) -- unfortunately it
doesn't have the same semantics as the #pragma pack() for x86-windows32.

Again, if you're not building on a native windows machine and need to
interface to system libraries, you're perfectly safe since gcc is
self-consistent.

Regards,
Mumit


Aki M Laukkanen

unread,
Mar 4, 2000, 3:00:00 AM3/4/00
to
In article <slrn8bdkjv...@grante.comtrol.com>, Grant Edwards wrote:
>You need to use __attribute__((packed)) like this:
>
>struct
>{
>char a[3] __attribute__((packed));
>char b[1] __attribute__((packed));
>}foo;
>
>Warning: while this will make sure that there are no empty
>spaced _between_ fields, it is not possible, AFAICT, to make
>sure there is no empty space at the end of the struct. E.g.
>there might not be any empty space before a or between a and b,
>but sizeof foo might be greater than 4.


Surely this would work?

struct foo
{
char a[3];
char b[1];
} __attribute__((packed));

--
D.

Grant Edwards

unread,
Mar 5, 2000, 3:00:00 AM3/5/00
to
On 4 Mar 2000 21:48:23 GMT, Aki M Laukkanen <amla...@cc.helsinki.fi> wrote:

>>struct
>>{
>>char a[3] __attribute__((packed));
>>char b[1] __attribute__((packed));
>>}foo;
>>
>>Warning: while this will make sure that there are no empty
>>spaced _between_ fields, it is not possible, AFAICT, to make
>>sure there is no empty space at the end of the struct. E.g.
>>there might not be any empty space before a or between a and b,
>>but sizeof foo might be greater than 4.
>
>
>Surely this would work?
>
>struct foo
>{
>char a[3];
>char b[1];
>} __attribute__((packed));

Not when I tried it with an ARM target.

I had a structure that looked something like this:

typedef struct
{
unsigned char dest[6] __attribute__((packed));
unsigned char src[6] __attribute__((packed));
unsigned short protNum __attribute__((packed));
} etherHeader __attribute__((packed));

Code generated for a 386 seemed work as I expected, but for an
ARM, sizeof (etherHeader) was 16. 14 was what I wanted.

--
Grant Edwards grante Yow! My mind is a potato
at field...
visi.com

Aki M Laukkanen

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
In article <jTmw4.377$F7....@ptah.visi.com>, Grant Edwards wrote:
>Code generated for a 386 seemed work as I expected, but for an
>ARM, sizeof (etherHeader) was 16. 14 was what I wanted.

Ok, I was sufficiently annoyed to check this because I had in other
context defended using packed attribute for writing portable
(well portable across gcc platforms) and interoperable software.
Guess I have to rething that position. It is just that I wanted to
take the lazy way.

Anyway this came up in gcc/config/arm/arm.h:

/* Every structures size must be a multiple of 32 bits. */
/* This is for compatibility with ARMCC. ARM SDT Reference Manual
(ARM DUI 0020D) page 2-20 says "Structures are aligned on word
boundaries". */
#ifndef STRUCTURE_SIZE_BOUNDARY
#define STRUCTURE_SIZE_BOUNDARY 32
#endif

I could argue that when using a gcc specific keyword compatibility to
armcc wouldn't be a top priority. And that is why in gcc/stor_layout.c:

#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
if (! TYPE_PACKED (rec))
record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY);
#endif

So I'm a bit puzzled. Which gcc version are you using? This is from
gcc 2.95.2.

--
D.

Grant Edwards

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
In article <slrn8c7h8c....@sirppi.helsinki.fi>, Aki M Laukkanen wrote:
>In article <jTmw4.377$F7....@ptah.visi.com>, Grant Edwards wrote:
>>Code generated for a 386 seemed work as I expected, but for an
>>ARM, sizeof (etherHeader) was 16. 14 was what I wanted.

[...]

>So I'm a bit puzzled. Which gcc version are you using? This is from
>gcc 2.95.2.

$ arm-elf-gcc --version
2.95.2


Here's the code:

------------------------------------------------------------

#define WORD unsigned short
#define BYTE unsigned char

typedef struct tagETH_ADDR
{
BYTE ea_bytes[6] __attribute__((packed));
} ETH_ADDR;

typedef struct tagETH_HEADER
{
BYTE daddr[6] __attribute__((packed));
BYTE saddr[6] __attribute__((packed));
WORD type __attribute__((packed));
} ETH_HEADER __attribute__((packed));

int gccEthHeaderSize = sizeof (ETH_HEADER);

------------------------------------------------------------

The variable gccEthHeaderSize is initialized to 16. I expected
it to be 14. I verified that there is no space between the
elements in the struct.

--
Grant Edwards grante Yow! A dwarf is passing
at out somewhere in Detroit!
visi.com

Aki M Laukkanen

unread,
Mar 7, 2000, 3:00:00 AM3/7/00
to
In article <slrn8c7ndq...@grante.comtrol.com>, Grant Edwards wrote:

> BYTE daddr[6] __attribute__((packed));
> BYTE saddr[6] __attribute__((packed));
> WORD type __attribute__((packed));
> } ETH_HEADER __attribute__((packed));

Btw. declaring individual fields packed should be unnecessary if the
whole structure is packed.



>The variable gccEthHeaderSize is initialized to 16. I expected
>it to be 14. I verified that there is no space between the
>elements in the struct.

So I got more annoyed by this and built a cross-compiler tool-chain.
The only difference to your configuration seems to be the elf target
whereas I used old binutils which had support only for coff.

--a.c--
struct foo
{
char a[6] __attribute__((packed));
char b[6] __attribute__((packed));
short c __attribute__((packed));
} __attribute__((packed));

int size = sizeof (struct foo);
--a.c--

I also tested all the permutations of packed attributes you could think
of.

Without attribute packed:

--a.s--
@ Generated by gcc 2.95.2 19991024 (release) for ARM/coff
gcc2_compiled.:
.global _size
.data
.align 0
_size:
.word 16
--a.s--

With structure defined as packed:

--a.s--
@ Generated by gcc 2.95.2 19991024 (release) for ARM/coff
gcc2_compiled.:
.global _size
.data
.align 0
_size:
.word 14
--a.s--

So this could be an elf/coff issue, except that structure boundary size is
defined exactly the same in gcc/config/arm/elf.h and gcc/config/arm/coff.h.

Have you tried with -mstructure-size-boundary=8 and
-mstructure-size-boundary=32? Is there a difference?

If this is not a self-compiled tool-chain I'd suggest you to recompile it
and try again. Otherwise you should report this to gcc folks because the
behavior should be as shown here.

--
D.

Grant Edwards

unread,
Mar 7, 2000, 3:00:00 AM3/7/00
to
In article <slrn8cadto....@sirppi.helsinki.fi>, Aki M Laukkanen wrote:

>> BYTE daddr[6] __attribute__((packed));
>> BYTE saddr[6] __attribute__((packed));
>> WORD type __attribute__((packed));
>> } ETH_HEADER __attribute__((packed));
>
>Btw. declaring individual fields packed should be unnecessary if the
>whole structure is packed.

That was my initial assumption. When it didn't work, I started
adding more __attribute__ tags.

>So I got more annoyed by this and built a cross-compiler tool-chain.
>The only difference to your configuration seems to be the elf target
>whereas I used old binutils which had support only for coff.

[packed attribute working as expected]

>So this could be an elf/coff issue, except that structure
>boundary size is defined exactly the same in
>gcc/config/arm/elf.h and gcc/config/arm/coff.h.
>
>Have you tried with -mstructure-size-boundary=8 and
>-mstructure-size-boundary=32? Is there a difference?

I'll try that some time.

>If this is not a self-compiled tool-chain I'd suggest you to
>recompile it and try again. Otherwise you should report this to
>gcc folks because the behavior should be as shown here.

It's a tool chain I built.

Is this strictly a function of gcc, or are binutils involved in
the alignment/packing decisions?

--
Grant Edwards grante Yow! Now, let's SEND OUT
at for QUICHE!!
visi.com

Grant Edwards

unread,
Mar 7, 2000, 3:00:00 AM3/7/00
to

>[packed attribute working as expected]

I'm generating code for big-endian arm7tdmi in case that
matters...

--
Grant Edwards grante Yow! ... I don't like
at FRANK SINATRA or his
visi.com CHILDREN.

Aki M Laukkanen

unread,
Mar 8, 2000, 3:00:00 AM3/8/00
to
In article <slrn8cai6r...@grante.comtrol.com>, Grant Edwards wrote:
>Is this strictly a function of gcc, or are binutils involved in
>the alignment/packing decisions?

Atleast as much is certain that binutils comes to play only after the
assembly is produced. I don't know much about the gas/ld side of things.

--
D.

0 new messages