在C ++中检查结构是否良好对齐或包含间隙

时间:2016-07-27 12:47:00

标签: c++ c

我有一个问题,即在编译时应检查结构 - 如果它已经很好地对齐或者它是否包含间隙。 检查可以在其他测试代码中完成,但我不希望在实际实现代码中使用“打包”数据。

这是一个带有典型包含警卫的示例头文件(MyData.h):

http.ErrUseLastResponse

我找到了一种可能的解决方案 - 见下文。

问题:

  • 编译时,是否有一种优雅的方法来检查struct #ifndef MYDATA_H_ #define MYDATA_H_ struct uneven { int bla_u32; short bla_u16; char bla_u8; /* <-- this gap will be filled in the unpacked version */ }; #endif // MYDATA_H 是否包含与其解包对应字节不同的字节数?

  • 是否有可能在C中使用的解决方案(不使用命名空间)?

3 个答案:

答案 0 :(得分:5)

适用于C和C ++的特定于编译器的解决方案:GCC有一个警告选项-Wpadded,它会为每个因对齐而改变大小的定义生成警告。

答案 1 :(得分:3)

您可以使用函数而不是命名空间(on ideone):

此解决方案也适用于C

标题文件:

typedef struct
{
  int bla_u32;
  short bla_u16;
  char bla_u8;

  /* <-- this gap will be filled in the unpacked version */
}  uneven;

源文件:

#include "MyData.h"

#define StaticAssert(cond, msg) switch(0){case 0:case cond:;}

void checkSizes()
{
  uneven unpacked_uneven;
#pragma pack(push, 1)
  #undef MYDATA_H_ // force re-including "MyData.h"
  #include "MyData.h"
#pragma pack(pop)
  uneven packed_uneven;
  StaticAssert(sizeof(unpacked_uneven) == sizeof(packed_uneven), "uneven contains gaps");
}

您可以将StaticAssert放入函数中以进行编译时错误。

答案 2 :(得分:2)

我找到了一个(某种程度上令人讨厌且非常棘手)解决方案,解决了只适用于C ++而不是C的问题。

uneven

对于给定的不均匀结构数据,此#define StaticAssert(cond, msg) switch(0){case 0:case cond:;} #pragma pack(push, 1) namespace packed { #include "MyData.h" } #pragma pack(pop) #undef MYDATA_H_ // force re-including "MyData.h" #include "MyData.h" void checkSizes() { StaticAssert(sizeof(packed::uneven) == sizeof(uneven), "uneven contains gaps"); } 宏失败 - 因为打包版本的大​​小为7个字节,而解压缩(正常)版本为8个字节。如果在结构的末尾添加了额外的StaticAssert,则测试成功 - 两个版本都有8个字节。