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

问题描述 投票:32回答:5

我想添加在编译期间检查结构大小的代码,以确保它是预定义的大小。例如,当我移植此代码或在编译期间添加/删除结构中的项时,我想确保此结构的大小为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++ data-structures static-assert
5个回答
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


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 );

6
投票

从C ++ 11开始,你有static_assert,它是在编译时处理的:

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

如果大小不是1024字节,您将收到编译错误。


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

在预处理器阶段做同样的事情是不可能的,但在你的情况下似乎并不真正需要。


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。

© www.soinside.com 2019 - 2024. All rights reserved.