seguidores pueden poner permite para los hashtags funcionan cuantos conseguir c++ data-structures static-assert

c++ - pueden - ¿Cómo verificar el tamaño de una estructura en tiempo de compilación?



hashtag web (5)

Quiero agregar un código que durante la compilación comprueba el tamaño de una estructura para asegurarse de que sea un tamaño predefinido. Por ejemplo, quiero asegurarme de que el tamaño de esta estructura sea de 1024 bytes cuando transfiera este código o cuando agregue / elimine elementos de la estructura durante el tiempo de compilación:

#pack(1) struct mystruct { int item1; int item2[100]; char item3[4]; char item5; char padding[615]; }

Sé cómo hacer esto durante el tiempo de ejecución usando un código como este:

if(sizeof(mystruct) != 1024) { throw exception("Size is not correct"); }

Pero es un desperdicio de procesamiento si lo hago durante el tiempo de ejecución. Necesito hacer esto durante el tiempo de compilación.

¿Cómo puedo hacer esto durante la compilación?


Desde C ++ 11 tienes static_assert que se maneja en la compilación:

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

Si el tamaño no es 1024 bytes, obtendrá un error de compilación.


Puedes verificar el tamaño durante la compilación:

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

Necesitas C ++ 11 para eso. Boost tiene una solución para los compiladores pre-c ++ 11:

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

Ver la documentación .


Si desea verificarlo en tiempo de compilación , puede usar la fase de metaprogramación de la plantilla.

En C ++ estándar tienes la BOOST_STATIC_ASSERT estática de boost, que está oculta por una macro BOOST_STATIC_ASSERT . Lo usarías de la siguiente manera:

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

El código anterior no podrá compilarse si la afirmación no se cumple, con algún mensaje de error semi legible.

En C ++ 11 obtienes una funcionalidad más simple con aserciones estáticas que introduce una nueva palabra clave static_assert .

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

No se puede hacer lo mismo en la fase de preprocesador , pero parece que no es realmente necesario en su caso.


Si no tiene C ++ 11 o Boost, puede intentar esto:

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

Si la declaración es falsa, este tipo define un tipo de matriz con un tamaño negativo, y su compilador debería dar un mensaje de error. Si es verdadero, entonces el tamaño será uno, un tamaño válido. Por ejemplo, g ++ da:

template.cpp:10:70: error: size of array ‘assertion_on_mystruct’ is negative

Admito que no es lo más útil, porque solo te dice el número de línea del error. Pero es la técnica más simple e independiente que se me ocurre.

Una macro más general es:

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


Tenga en cuenta que el relleno está incluido en sizeof ():

struct A { int i; bool b; }; typedef char assertion_on_A[( ((sizeof(A)))== 8 )*2-1 ]; static_assert(sizeof(A) == 8, "sizeof A");

Tanto el typedef como el static_assert esperan el tamaño 8 aquí.