Подтвердить что ты не робот

Как проверить размер структуры во время компиляции?

Я хочу добавить код, который во время компиляции проверяет размер структуры, чтобы убедиться, что это предопределенный размер. Например, я хочу убедиться, что размер этой структуры составляет 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");
 }

Но это пустая трата обработки, если я делаю это во время выполнения. Мне нужно сделать это во время компиляции.

Как это сделать во время компиляции?

4b9b3361

Ответ 1

Вы можете проверить размер во время компиляции:

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

Для этого вам нужен С++ 11. У Boost есть обходное решение для компиляторов pre-С++ 11:

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

См. документацию.

Ответ 2

Если у вас нет С++ 11 или Boost, вы можете попробовать следующее:

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

Если утверждение ложно, то это typedefs тип массива с отрицательным размером, и ваш компилятор должен дать сообщение об ошибке. Если true, тогда размер будет один, действительный размер. Например, 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 );

Ответ 3

Из С++ 11 у вас static_assert, который обрабатывается при компиляции:

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

Если размер не равен 1024 байтам, вы получите ошибку компиляции.

Ответ 4

Если вы хотите проверить его во время компиляции, вы можете использовать фазу метапрограммирования шаблона.

В стандартном С++ у вас есть boost static assert, который скрыт макросом BOOST_STATIC_ASSERT. Вы бы использовали его следующим образом:

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

Вышеприведенный код не сможет скомпилироваться, если утверждение не выполнено, с некоторым получитаемым сообщением об ошибке.

В С++ 11 вы получаете более простую функциональность с static assertions, в котором вводится новое ключевое слово static_assert.

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

Выполнение того же самого действия на этапе препроцессора не может быть выполнено, но в вашем случае это не очень важно.