views:

391

answers:

10
+5  A: 

I think your compiler uses 4-byte allignment for the fields.

alygin
Only the `int` fields.
Zooba
+7  A: 

The individual fields in a structure need to be aligned appropriately. The compiler will pad additional space in the structure in order to satisfy alignment requirements.

If you don't want this, you can use the UNALIGNED macro.

Anon.
I don't think `unaligned` is a keyword. That would be compiler specific.
GMan
The answer is good, but 'unaligned' is not a C++ keyword.
coppro
Specifically, in this case, it looks like 2 bytes of padding before the first `int` to align it to a 4-byte boundary. The shorts are aligned to 2-byte boundaries.
Mark Ransom
You are correct. The correct method is to use the `UNALIGNED` macro, which expands to the `__unaligned` keyword for alignment-sensitive architectures, or nothing otherwise. I'll edit that in.
Anon.
In GCC, you can use __attribute__((packed)); to indicate you want to un-align the fields. E.g.:unsigned short bfType __attribute__((packed));
Joey Adams
I'm pretty sure `UNALIGNED` as a macro is compiler specific too :)
GMan
`__unaligned` is a Visual C++ extension, and is not supported by e.g. g++ (which the question explicitly identifies as the implementation being used). Any such macro would be inherently implementation-specific.
Pavel Minaev
The alignment of each member has a minimum requirement (set by the hardware). But the compiler can add even more padding for other reasons (shuch as optimization).
Martin York
+12  A: 

It's because the 4 byte ints are aligned to a 4 byte boundry, so there are 2 bytes of padding after bfType.

Ramónster
+8  A: 

Alignment. Likely on your platform ints have to be 4byte aligned and shorts are 2byte aligned.

+0 -1 : bfType
+2 -3 : <padding>
+4 -7: bfSize
+8 -9: bfReserve1
+10 -11: bfReserve2
+12 -15: bfOffBits
-------------
16 bytes

Alignment is good because unaligned structures require extra work for many architectures.

Sanjaya R
A: 

because of the way memory is allocated, there will be padding after a short

Euclid
Indeed, that's a good suggestion. However, the application here relates to processing .bmp files, so that's not an option. +1 anyway ;-)
Joey Adams
A: 

This is due to alignment - the compiler has to do some padding.

rmn
+1  A: 

U can pragma pack the structure to avoid padding

tomkaith13
+1  A: 

ISO C++03, 9.2[class.mem]/12:

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

Pavel Minaev
+2  A: 

This issue comes because of a concept known as alignment. In many cases, it is desirable to have a number placed at an address that is a multiple of the size of the number in bytes (up to some maximum, often the pointer size of the platform). A variable so placed is said to be aligned to a n-byte boundary, where n is the number. The exact effects of this depend on the processor. Many processors perform math faster if the data is properly aligned. Some are even incapable of performing operations (sometimes even load operations) on unsuitably-aligned data - in order to work on such data, it has to be loaded into two registers and then a series of bit shifts and masks need to be performed to get a usable value, and then it needs to be put back. Think of it like storing half of the int in each of two buckets and needing to put them together to use it, rather than simply storing the whole int in one bucket.

In your case, the initial bfType likely needs to be aligned to a 2-byte boundary, while bfSize likely needs to be aligned to a 4-byte boundary. The compiler has to accomodate this by aligning the entire struct to 4 bytes, and leaving 2 unused bytes between bfType and bfSize.

When compiling on the same system, however, the padding is probably going to be consistent, possibly depending on compiler options and the specific ABI used (generally, you're safe on the same platform unless you are trying to make things incompatible). You can freely make another struct with the same first 5 members, and they will take up 16 bytes of the other struct, in the exact same positions.

If you really need to avoid this behavior, you will have to check your compiler documentation. Most compilers offer an attribute or keyword to declare a variable as having no alignment, and another one to indicate that a struct should have no padding. But these are rarely necessary in the general course of things.

coppro
A: 

Just remember:

  1. The size of a structure may not equal the sum of the size of the fields.
  2. Don't use structures a data stencils. They can model the data. Problems arise otherwise.
  3. The data should be assigned to the members individually; don't use memcpy or fread or istream::read.

If you feel that this is a performance issue, allocate a huge unsigned char buffer, read data into the buffer then assign from buffer to the members of the structure. Remember that memory transfers are faster the I/O transfers.

Thomas Matthews