Wireshark-dev: Re: [Wireshark-dev] R: Problems encountered on Windows building from a "source t
Loris Degioanni wrote:
I've consistently seen both VC and gcc putting padding between values in
an array, especially in a case like this one: there's good chance that
dur will be at byte 4 instead of 2.
You've seen padding placed between arrays of "unsigned char"? On what
CPU? I wouldn't expect that on x86 - there is a penalty for unaligned
accesses with some x86 processors, but it is supported natively.
According to the GCC 4.1.1 manual, "the alignment of non-bit-field
members of structures (C90 6.5.2.1, C99 6.7.2.1)" is "determined by
ABI"; the i386 ABI manual at
http://www.sco.com/developers/devspecs/abi386-4.pdf
says on page 28 that "char" and "unsigned char" are aligned on byte
boundaries, and says on page 29 that "an array uses the same
alignment as its elements" and that "each member [of a structure or
union] is assigned to the lowest available offset with the appropriate
alignment", which would put "dur" at byte 2. I can check some other ABI
documents I have to see what they say, although I don't have any for
ARM, for example.
Microsoft's documentation says
Every data object has an alignment-requirement. The
alignment-requirement for all data except structures, unions, and arrays
is either the size of the object or the current packing size (specified
with either /Zp or the pack pragma, whichever is less). For structures,
unions, and arrays, the alignment-requirement is the largest
alignment-requirement of its members. Every object is allocated an
offset so that
offset % alignment-requirement == 0
The description of the /Zp option is:
When you specify this option, each structure member after the first is
stored on either the size of the member type or n-byte boundaries (where
n is 1, 2, 4, 8, or 16), whichever is smaller.
so it won't force stricter alignment.
The documentation also says of "#pragma pack(n)":
Specifies the value, in bytes, to be used for packing. The default
value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of
a member will be on a boundary that is either a multiple of n or a
multiple of the size of the member, whichever is smaller.
so that reduces, but doesn't increase, alignment requirements.
To avoid the problem, I use #pragma
pack with VC, and __attribute__((__packed__)) with GCC
typedef struct _foo
{
char first;
char second;
}__attribute__((__packed__))
foo;
With the right #ifdefs, you can easily make the thing portable.
What would you put inside the #ifdefs for Sun C, IBM xlc, and HP's C
compiler - all three of those are used to compile Wireshark?