tamaño - ¿Cómo puedo imprimir el resultado de sizeof() en tiempo de compilación en C?
sizeof implementation (6)
¿Cómo puedo imprimir el resultado de sizeof () en tiempo de compilación en C?
Por ahora estoy usando una aserción estática (elaboración casera basada en otros recursos web) para comparar el resultado de sizeof () con varias constantes. Si bien esto funciona ... está lejos de ser elegante o rápido. También puedo crear una instancia de la variable / estructura y buscar en el archivo de mapa, pero esto también es menos elegante y rápido que una llamada / comando / operador directo. Además, este es un proyecto integrado que utiliza varios compiladores cruzados ... así que crear y cargar un programa de muestra en el objetivo y luego leer un valor es incluso más complicado que cualquiera de los anteriores.
En mi caso (antiguo GCC), #warning sizeof(MyStruct)
realidad no interpreta sizeof () antes de imprimir la advertencia.
Aunque esto no es exactamente en el momento de la compilación, es antes del tiempo de ejecución, por lo que aún podría ser relevante para algunas personas.
Puedes definir una matriz así:
uint8_t __some_distinct_name[sizeof(YourTypeHere)];
Y luego, después de la compilación, obtenga el tamaño del archivo de objeto:
$ nm -td -S your_object_file | # list symbols and their sizes, in decimal
grep '' __some_distinct_name$'' | # select the right one
cut -d'' '' -f2 | # grab the size field
xargs printf "Your type is %d B/n" # print
Estaba buscando una funcionalidad similar cuando me topé con esto:
¿Es posible imprimir el tamaño de una clase de C ++ en tiempo de compilación?
Lo que me dio la idea para esto:
char (*__kaboom)[sizeof( YourTypeHere )] = 1
Lo que resulta en la siguiente advertencia en VS2015:
warning C4047: ''initializing'': ''DWORD (*)[88]'' differs in levels of indirection from ''int''
Donde 88 en este caso sería el tamaño que estás buscando.
Super hacky, pero hace el truco. Probablemente un par de años demasiado tarde, pero espero que esto sea útil para alguien.
Todavía no he tenido la oportunidad de probar con gcc o clang, pero trataré de confirmar si funciona o no si alguien no lo hace antes que yo.
Edit: Trabaja fuera de la caja para Clang 3.6
El único truco en el que podía trabajar para GCC era abusar de -formar y tener la macro para definir una función como la siguiente:
void kaboom_print( void )
{
printf( "%d", __kaboom" );
}
Lo que te dará una advertencia como:
...blah blah blah... argument 2 has type ''char (*)[88]''
Un poco más grosero que la sugerencia original, pero tal vez alguien que conozca a gcc un poco mejor pueda pensar en una mejor advertencia de abuso.
Me encontré con una solución similar a la gran solución de , y esta produce una advertencia mucho menos verbosa, por lo que puede resultarle útil:
char (*__fail)(void)[sizeof(uint64_t)] = 1;
Esto produce el mensaje de error
Function cannot return array type ''char [8]''
Esto fue probado con la última versión de clang(1)
.
Mi compilador gcc C se niega a imprimir el tamaño utilizando cualquiera de las soluciones anteriores. Invertí la lógica para inyectar advertencias del compilador de qué tamaño no es.
enum e
{
X = sizeof(struct mystruct)
};
void foo()
{
static enum e ev;
switch (ev)
{
case 0:
case 4:
case 8:
case 12:
case 16:
case 20:
break;
}
}
Entonces tengo que mirar a través de las advertencias para el número que falta.
warning: case value ''0'' not in enumerated type ''e'' [-Wswitch]
warning: case value ''4'' not in enumerated type ''e'' [-Wswitch]
warning: case value ''12'' not in enumerated type ''e'' [-Wswitch]
warning: case value ''16'' not in enumerated type ''e'' [-Wswitch]
warning: case value ''20'' not in enumerated type ''e'' [-Wswitch]
Entonces mi tamaño de estructura es 8
Mi embalaje es 4.
Meh ... es una opción.
No puedes hacer esto, no con estructuras. El preprocesador se invoca antes de que tenga lugar la compilación, por lo que ni siquiera existe el concepto de estructura; no se puede evaluar el tamaño de algo que no existe / no se definió. El preprocesador tokeniza una unidad de traducción, pero lo hace solo con el propósito de localizar la invocación de macros.
Lo más cercano que puede tener es confiar en algunas macros definidas por la implementación que evalúan el tamaño de los tipos incorporados. En gcc, puedes encontrar aquellos con:
gcc -dM -E - </dev/null | grep -i size
Que en mi sistema imprimió:
#define __SIZE_MAX__ 18446744073709551615UL
#define __SIZEOF_INT__ 4
#define __SIZEOF_POINTER__ 8
#define __SIZEOF_LONG__ 8
#define __SIZEOF_LONG_DOUBLE__ 16
#define __SIZEOF_SIZE_T__ 8
#define __SIZEOF_WINT_T__ 4
#define __SIZE_TYPE__ long unsigned int
#define __SIZEOF_PTRDIFF_T__ 8
#define __SIZEOF_FLOAT__ 4
#define __SIZEOF_SHORT__ 2
#define __SIZEOF_INT128__ 16
#define __SIZEOF_WCHAR_T__ 4
#define __SIZEOF_DOUBLE__ 8
#define __SIZEOF_LONG_LONG__ 8
Realmente no hay nada que puedas hacer para saber el tamaño de una estructura personalizada sin escribir un programa y ejecutarlo.
Todo lo que necesita es un truco que hace que el compilador se queje por el uso incorrecto de algunos valores enteros de tiempo de compilación, como la constante de un case
duplicado:
struct X {
int a,b;
int c[10];
};
int _tmain(int argc, _TCHAR* argv[])
{
int dummy;
switch (dummy) {
case sizeof(X):
case sizeof(X):
break;
}
return 0;
}
------ Se inició la compilación: Proyecto: cpptest, Configuración: Depuración Win32 ------ cpptest.cpp c: / work / cpptest / cpptest / cpptest.cpp (29): error C2196: valor de caso ''48'' ya se utilizó ========== Compilación: 0 se realizó correctamente, 1 falló, 0 se actualizó, 0 se omitió ==========
Así que el tamaño de la estructura X es 48