Вопрос

For the below structure, the actual (with no padding) size of the structure is 54. On a 64-bit (Windows 7) machine with MinGW (GCC) 4.8.1 x86_64, I get sizeof(BMPHeader) as 56, which is understandable. As per the requirement of the BMP file format, the structure should've no padding. I've three options (priority ordered):

  1. C++11's alignas(1)
  2. struct __attribute__ ((packed)) BMPHeader
  3. #pragma pack(1)

However the last option (with least priority) alone seems to work giving me 54. Is this a bug in the compiler or I've completely mistook something here? The SSCCE

#include <iostream>

struct alignas(1) BMPHeader
{
    // BMP header
    uint16_t magic;
    uint32_t fileSize;
    uint32_t reserved;
    uint32_t dataOffset;

    // DIB header
    uint32_t dibHeaderLength;
    uint32_t width;
    uint32_t height;
    uint16_t numColourPlanes;
    uint16_t bitsPerPixels;
    uint32_t biBitFields;
    uint32_t dataSize;
    uint32_t physicalWidth;
    uint32_t physicalHeight;
    uint32_t numPaletteColours;
    uint32_t numImportantColours;
};

int main()
{
    std::cout << sizeof(BMPHeader) << std::endl;
}
Это было полезно?

Решение

  1. alignas cannot be used in this situation as Martinho notes, since we're asking for an alignment less stricter than the natural alignment of the struct. This is specified in the standard under dcl.align (emphasised the relevant part):

When multiple alignment-specifiers are specified for an entity, the alignment requirement shall be set to the strictest specified alignment.

The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers were omitted (including those in other declarations).

The alignment of BMPHeader as returned by alignof(BMPHeader) is 4 and thus any alignment less stricter (less wider) than that wouldn't be honoured.

  1. __attribute__ ((packed)) is certainly the right way when using GCC as specified in its manual to make a struct tightly packed. However, this doesn't work due to a bug in MinGW and works fine when using GCC.

  2. So currently the only way in MinGW is to make-do with #pragma pack(1). See #pragma pack effect for more details on this method.

See Also

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top