2008-09-26 28 views
35

Estoy buscando un fragmento de código que pueda indicarme el desplazamiento de un campo dentro de una estructura sin asignar una instancia de la estructura.C/C++ Desplazamiento de estructura

IE: dado

struct mstct { 
    int myfield; 
    int myfield2; 
}; 

podría escribir:

mstct thing; 
printf("offset %lu\n", (unsigned long)(&thing.myfield2 - &thing)); 

Y conseguir "compensado 4" para la salida. ¿Cómo puedo hacerlo sin esa declaración de "cosa mstct"/asignación de una?

Sé que & <struct> estructura no siempre apunta al primer byte del primer campo de la estructura, puedo explicar eso más adelante.

Respuesta

69

¿Qué hay de la macro offsetof() estándar (en stddef.h)?

Editar: para las personas que no pudieron tener la offsetof() macro disponible por alguna razón, se puede obtener el efecto de usar algo como:

#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field)) 
+1

No exactamente lo que quería, porque no tengo stddef.h, pero responde mi pregunta con: #define offsetof (TYPE, MEMBER) ((size_t) & ((TYPE *) 0) -> MIEMBRO) – davenpcj

+3

Wow - no stddef.h? Solo por curiosidad, ¿podría preguntar qué estás usando? –

+0

Está en el estándar C99, por lo que sugeriría obtener un nuevo compilador. – wnoise

8

derecha, utilice la macro offsetof, que (al menos con GNU CC) está disponible tanto para C y C++ código:

offsetof(struct mstct, myfield2) 
+0

offsetof() ha estado en C/C++ estándar desde el primer estándar ANSI C89. Cada compilador debería tenerlo, a menos que estés usando algo muy antiguo. Incluso entonces podría ser improvisado utilizando feos cálculos aritméticos y punteros. –

+0

Estoy de acuerdo: probablemente proporcione un dummy para proporcionar esas macros. Plauger proporciona "The Standard C Library" y es un encabezado fácil de proporcionar, siempre que no tenga que ser portátil. –

+0

AFAIK, offsetof() no es hing * pero * feo fundición y aritmética de puntero ... algo así como: #define offsetof (tipo, campo) ((char *) & (((tipo *) 0) -> campo) - (char *) 0) –

3

printf ("offset:% d \ n", & ((mstct *) 0) -> myfield2);

+1

Además del hecho de que 'offsetof' hace esto de una manera más legible, generalmente no se puede imprimir un' ptrdiff_t' con '% d' - en sistemas LP64, es demasiado grande. –

Cuestiones relacionadas