Reputation: 711
I can use pragma pack on various compilers to force structs to have fields which are not on their natural alignments.
Is this recursive - so suppose struct typedef A contains a field of typedef struct B. If use a pragma to pack A will this force struct B to be packed?
Upvotes: 3
Views: 3646
Reputation: 93446
You have to hope not! Lets say you have a function that takes a parameter struct A:
void fn( struct A x ) ;
and then a packed struct B that has struct A as a member:
#pragma pack(1)
struct B
{
struct A a ;
}
If you pass the member a of B to fn(), the function has no knowledge of the packing in this instance, and would fail.
Other answerer's results notwithstanding, I performed the following test on VC++ 2010:
struct A
{
int a;
char b;
int c ;
} ;
struct B
{
struct A d ;
} ;
#pragma pack(1)
struct C
{
struct A d ;
} ;
#pragma pack(1)
struct D
{
int a;
char b;
int c ;
} ;
#pragma pack(1)
struct E
{
struct D ;
} ;
int main()
{
int a = sizeof(struct A) ;
int b = sizeof(struct B) ;
int c = sizeof(struct C) ;
int d = sizeof(struct D) ;
int e = sizeof(struct E) ;
}
Inspection of a, b, c, d and e in main() in the debugger yield:
The packing of struct C
has no effect on the size of its struct A member.
Upvotes: 6
Reputation: 108968
Folowing Nathon's post, I tried about the same thing on my computer:
#include <stdio.h>
#if defined PACK_FIRST || defined PACK_BOTH
#pragma pack(1)
#endif
struct inner {
char a;
double b;
};
#if defined PACK_SECOND || defined PACK_BOTH
#pragma pack(1)
#endif
struct outer {
char a;
struct inner b;
char c;
double d;
};
int main(void) {
printf("sizeof (char): %d (1, of course)\n", (int)sizeof (char));
printf("sizeof (double): %d\n", (int)sizeof (double));
printf("sizeof (inner): %d\n", (int)sizeof (struct inner));
printf("sizeof (outer): %d\n", (int)sizeof (struct outer));
return 0;
}
$ gcc 4128061.c $ ./a.out sizeof (char): 1 (1, of course) sizeof (double): 8 sizeof (inner): 16 sizeof (outer): 40 $ gcc -DPACK_FIRST 4128061.c $ ./a.out sizeof (char): 1 (1, of course) sizeof (double): 8 sizeof (inner): 9 sizeof (outer): 19 $ gcc -DPACK_SECOND 4128061.c $ ./a.out sizeof (char): 1 (1, of course) sizeof (double): 8 sizeof (inner): 16 sizeof (outer): 26 $ gcc -DPACK_BOTH 4128061.c $ ./a.out sizeof (char): 1 (1, of course) sizeof (double): 8 sizeof (inner): 9 sizeof (outer): 19
Apparently my gcc packs from the point where the #pragma
line appears.
Upvotes: 4
Reputation: 50943
For the version of GCC I have handy, it looks like yes:
#include <stdio.h>
typedef struct
{
char a;
int b;
}inner_t;
#pragma pack(1)
typedef struct
{
char a;
inner_t inner;
} outer_t;
int main()
{
outer_t outer;
outer.inner.a = 'a';
outer.inner.b = 0xABCDEF01;
printf ("outer.inner.a: %c\n", outer.inner.a);
return 0;
}
And gdb breaking on the printf gives me...
(gdb) x/5xw &outer
0x7fffffffe4b0: 0xffff61a0 0xcdef01ff 0x000000ab 0x00000000
0x7fffffffe4c0: 0x00000000
inner.b
is not word aligned. So under GCC 4.4.5 on a little endian 64-bit machine, nested structures are packed if the outer structure is packed. Pardon my typedefs, those of you who don't like them.
Upvotes: 1
Reputation: 215193
Just don't. The exact behavior of an ugly nonstandard extension is not something you can even ask questions about without specifying an exact platform/compiler you're working with. If you find yourself needing packed structs, you'd be better to figure out why your code is broken and fix it. Packed structs are a band-aid for broken code that do nothing to fix the root cause of the brokenness.
Upvotes: 5