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

时间:2013-10-16 11:11:52

标签: c++ data-structures static-assert

我想添加在编译期间检查结构大小的代码,以确保它是预定义的大小。例如,当我移植此代码或在编译期间添加/删除结构中的项时,我想确保此结构的大小为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");
 }

但如果我在运行期间这样做,那就浪费了处理能力。我需要在编译期间这样做。

如何在编译期间执行此操作?

5 个答案:

答案 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");

请参阅the documentation

答案 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。