我想添加在编译期间检查结构大小的代码,以确保它是预定义的大小。例如,当我移植此代码或在编译期间添加/删除结构中的项时,我想确保此结构的大小为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");
}
但如果我在运行期间这样做,那就浪费了处理能力。我需要在编译期间这样做。
如何在编译期间执行此操作?
答案 0 :(得分:34)
您可以在编译期间检查尺寸:
static_assert (sizeof(mystruct) == 1024, "Size is not correct");
你需要C ++ 11。 Boost为pre-c ++ 11编译器提供了一种解决方法:
BOOST_STATIC_ASSERT_MSG(sizeof(mystruct) == 1024, "Size is not correct");
答案 1 :(得分:19)
如果你没有C ++ 11或Boost,你可以试试这个:
typedef char assertion_on_mystruct[( sizeof(mystruct)==1024 )*2-1 ];
如果该语句为false,则此类型提供具有负大小的数组类型,并且您的编译器应该给出错误消息。如果为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 );
答案 2 :(得分:6)
从C ++ 11开始,你有static_assert
在编译时处理:
static_assert(sizeof(mystruct) == 1024, "Size is not correct");
如果大小不是1024
字节,则会出现编译错误。
答案 3 :(得分:4)
如果要在编译时进行检查,可以使用模板元编程阶段。
在标准C ++中,你有static assert,它被宏BOOST_STATIC_ASSERT
隐藏。
您可以通过以下方式使用它:
#include <boost/static_assert.hpp>
...
BOOST_STATIC_ASSERT(sizeof(mystruct) == 1024);
如果不满足断言,上面的代码将无法编译,并带有一些半可读的错误消息。
在C ++ 11中,您可以使用static assertions获得更简单的功能,从而引入新的关键字static_assert
。
static_assert(sizeof(mystruct) == 1024,"Size is not correct");
在预处理器阶段执行相同的操作无法完成,但在您的情况下似乎并不需要。
答案 4 :(得分:1)
请注意,填充包含在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。