MinGW和使用C ++ 11打包结构对齐 [英] MinGW and packed struct alignment using C++11

查看:307
本文介绍了MinGW和使用C ++ 11打包结构对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于下面的结构,结构中的实际的(没有填充)大小是54.在具有MinGW(GCC)4.8.1 x86_64的64位(Windows 7)计算机上,I得到 sizeof(BMPHeader)为56,这是可以理解的。根据BMP文件格式的要求,结构应该没有填充。我有三个选项(按优先顺序排列):


  1. C ++ 11's alignas(1) $ struct __attribute__((packed))BMPHeader

  2. #pragma pack(1)

然而,最后一个选项工作给了我54.这是编译器中的一个错误还是我完全误解了一些东西? SSCCE

  #include< iostream> 
$ b $ struct alignas(1)BMPHeader
{
// BMP header
uint16_t magic;
uint32_t fileSize;
uint32_t保留;
uint32_t dataOffset;

// DIB标题
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. Martinho指出,在这种情况下不能使用 alignas ,因为我们要求对齐比结构的自然对齐更严格。这在 dcl.align 标准下指定(强调相关部分):

    $ b


    当为实体指定多个对齐说明符时,对齐要求应设置为最严格的指定对齐方式。



    所有对齐说明符的组合效果在一个声明中不应该指定一个对齐方式,如果省略所有对齐方式说明符()(包括其他声明中的那些对象说明符),那么该对齐方式将比实体声明所需的对齐方式更为严格。




    BMPHeader alignof(BMPHeader) 4 ,因此任何对齐不会更严格(更宽),不会被兑现。


    1. __ attribute__((packed))当然是将GCC用作在其手册中指定,以使结构紧凑。但是,由于MinGW中存在错误,因此这种方法无效使用GCC时正常运行


    2. 因此,目前MinGW的唯一方法是使用 #pragma pack(1)进行配制。有关此方法的更多详细信息,请参阅 #pragma pack effect
      ol>

      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.

      这篇关于MinGW和使用C ++ 11打包结构对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆