如何在编译时检查结构的大小

How to check the size of a structure at compile time?

本文关键字:结构 检查 编译      更新时间:2023-10-16

我想添加代码,在编译期间检查结构的大小以确保它是预定义的大小。例如,我想确保在移植此代码或在编译时从结构中添加/删除项目时,此结构的大小为 1024 字节:

#pack(1)
struct mystruct
{
    int item1;
    int item2[100];
    char item3[4];
    char item5;
    char padding[615];
 }

我知道如何在运行时使用如下代码执行此操作:

 if(sizeof(mystruct) != 1024)
 { 
     throw exception("Size is not correct");
 }

但是,如果我在运行时执行此操作,则浪费了处理。我需要在编译时执行此操作。

如何在编译过程中执行此操作?

从 C++11 开始,您可以在编译期间检查大小:

static_assert (sizeof(mystruct) == 1024, "Size is not correct");

在 c++11 之前,Boost 有一个解决方法:

BOOST_STATIC_ASSERT_MSG(sizeof(mystruct) == 1024, "Size is not correct");

请参阅文档。

如果你没有 C++11 或 Boost,你可以试试这个:

typedef char assertion_on_mystruct[(   sizeof(mystruct)==1024   )*2-1 ];

如果语句为 false,则此 typedef 为负大小的数组类型,编译器应给出错误消息。 如果为 true,则大小将为 1,即有效大小。 例如,g++ 提供:

template.cpp:10:70: error: size of array ‘assertion_on_mystruct’ is negative

我承认这不是最有用的东西,因为它只告诉你错误的行号。 但这是我能想到的最简单、最独立的技术。

更通用的宏是:

#define DUMB_STATIC_ASSERT(test) typedef char assertion_on_mystruct[( !!(test) )*2-1 ]
DUMB_STATIC_ASSERT( sizeof(mystruct)==1024 );
DUMB_STATIC_ASSERT( sizeof(my_other_struct)==23 );
DUMB_STATIC_ASSERT( sizeof(minimum_size_struct) >= 23 );

从 C++11 开始,您有static_assert编译时处理:

static_assert(sizeof(mystruct) == 1024, "Size is not correct");

如果大小不是 1024 字节,则会出现编译错误。

如果你想在编译时检查它,你可以使用模板元编程阶段。

在标准C++中,你有 boost 的静态断言,它被宏BOOST_STATIC_ASSERT隐藏。您将按以下方式使用它:

#include <boost/static_assert.hpp>
...
BOOST_STATIC_ASSERT(sizeof(mystruct) == 1024);

如果不满足断言,上面的代码将无法编译,并显示一些半可读的错误消息。

在 C++11 中,您可以使用静态断言获得更简单的功能,这引入了一个新的关键字 static_assert

static_assert(sizeof(mystruct) == 1024,"Size is not correct");

预处理器阶段做同样的事情是无法完成的,但在您的情况下似乎并不真正需要。

请注意,填充包含在 sizeof() 中:

struct A { int i; bool b; };
typedef char assertion_on_A[( ((sizeof(A)))== 8 )*2-1 ];
static_assert(sizeof(A) == 8, "sizeof A");

typedef 和 static_assert 都期望这里的尺寸为 8。