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
>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
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.
>
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
Surely this would work?
struct foo
{
char a[3];
char b[1];
} __attribute__((packed));
--
D.
>>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
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.
[...]
>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
> 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.
>> 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
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.
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.