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