¿Qué es una macro C / C ++ común para determinar el tamaño de un miembro de estructura?

StackOverflow https://stackoverflow.com/questions/1400660

  •  05-07-2019
  •  | 
  •  

Pregunta

En C / C ++, ¿cómo puedo determinar el tamaño de la variable miembro en una estructura sin necesidad de definir una variable ficticia de ese tipo de estructura? Aquí hay un ejemplo de cómo hacerlo mal, pero muestra la intención:

typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x);  // error

Como referencia, este debe ser el modo de encontrar el tamaño de 'x' si primero define una variable ficticia:

myStruct_t dummyStructVar;

const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);

Sin embargo, espero evitar tener que crear una variable ficticia solo para obtener el tamaño de 'x'. Creo que hay una forma inteligente de cambiar a 0 como myStruct_t para ayudar a encontrar el tamaño de la variable miembro 'x', pero ha pasado el tiempo suficiente como para que haya olvidado los detalles, y parece que no puedo obtener una buena búsqueda de Google en este . ¿Sabes?

¡Gracias!

¿Fue útil?

Solución

En C ++ (que es lo que dicen las etiquetas), tu " variable ficticia " El código puede ser reemplazado por:

sizeof myStruct_t().x;

No se creará ningún objeto myStruct_t: el compilador solo resuelve el tipo estático del operando sizeof, no ejecuta la expresión.

Esto funciona en C, y en C ++ es mejor porque también funciona para clases sin un constructor sin argumentos accesible:

sizeof ((myStruct_t *)0)->x

Otros consejos

Estoy usando la siguiente macro:

#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
    struct ABC
    {
        int a;
        char b;
        double c;
    };
    std::cout << "ABC::a=" << DIM_FIELD(ABC, a) 
              << " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;

    return 0;
}

El truco trata el 0 como puntero a tu estructura. Esto se resuelve en tiempo de compilación para que sea seguro.

Puedes hacerlo fácilmente

sizeof(myStruct().x)

Como el parámetro sizeof nunca se ejecuta, realmente no crearás ese objeto.

Cualquiera de estos debería funcionar:

sizeof(myStruct_t().x;);

o

myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)

o

sizeof(((myStruct_t *)NULL)->x);

Debido a que sizeof se evalúa en tiempo de compilación, no en tiempo de ejecución, no tendrá problemas para eliminar la referencia de un puntero NULL.

En C ++ 11, esto se puede hacer con sizeof (myStruct_t :: x) . C ++ 11 también agrega std :: declval , que puede usarse para esto (entre otras cosas):

#include <utility>
typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);

Desde el encabezado de mis macros de utilidad:

#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

invocado así:

FIELD_SIZE(myStruct_t, x);  
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top