Reputation: 18178
I want to add code that during compilation checks the size of a structure to make sure that it is a predefined size. For example I want to make sure that the size of this structure is 1024 byte when I am porting this code or when I am adding/removing items from structure during compile time:
#pack(1)
struct mystruct
{
int item1;
int item2[100];
char item3[4];
char item5;
char padding[615];
}
I know how to do this during run time by using a code such as this:
if(sizeof(mystruct) != 1024)
{
throw exception("Size is not correct");
}
But it is a waste of processing if I do this during run time. I need to do this during compile time.
How can I do this during compilation?
Upvotes: 46
Views: 34199
Reputation: 120031
Since C++11, you can check the size during compilation:
static_assert (sizeof(mystruct) == 1024, "Size is not correct");
Pre-c++11 compilers, Boost has a workaround:
BOOST_STATIC_ASSERT_MSG(sizeof(mystruct) == 1024, "Size is not correct");
See the documentation.
Upvotes: 40
Reputation: 703
Please note that padding is included in sizeof():
struct A { int i; bool b; };
typedef char assertion_on_A[( ((sizeof(A)))== 8 )*2-1 ];
static_assert(sizeof(A) == 8, "sizeof A");
Both the typedef and the static_assert expect size 8 here.
Upvotes: 2
Reputation: 27153
If you don't have C++11 or Boost, you could try this:
typedef char assertion_on_mystruct[( sizeof(mystruct)==1024 )*2-1 ];
If the statement is false, then this typedefs an array type with negative size, and your compiler should give an error message. If true, then the size will be one, a valid size. For example, g++ gives:
template.cpp:10:70: error: size of array ‘assertion_on_mystruct’ is negative
I admit it's not the most useful thing, because it only tells you the line number of the error. But it is the simplest, stand-alone, technique I can think of.
A more general macro is:
#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 );
Upvotes: 27
Reputation: 21818
If you want to check it at compile time you may use template metaprogramming phase.
In standard C++ you have boost's static assert, which is hidden by a macro BOOST_STATIC_ASSERT
.
You would use it in the following way:
#include <boost/static_assert.hpp>
...
BOOST_STATIC_ASSERT(sizeof(mystruct) == 1024);
The above code will fail to compile if the assertion is not met, with some semi-readable error message.
In C++11 you get simpler functionality with static assertions which introduces a new keyword static_assert
.
static_assert(sizeof(mystruct) == 1024,"Size is not correct");
Doing the same thing at preprocessor phase cannot be done but it seems not to be really needed in your case.
Upvotes: 4
Reputation: 409374
From C++11 you have static_assert
which is handled on compilation:
static_assert(sizeof(mystruct) == 1024, "Size is not correct");
If the size is not 1024
bytes, you will get a compilation error.
Upvotes: 7