2008-09-26 23 views
35

Yapının bir örneğini ayırmadan bir yapı içindeki bir alanın ofsetini anlatabilecek bir kod parçası arıyorum.C/C++ Yapı ofseti

IE:

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

Ve olsun çıkış için "4 offset":

struct mstct { 
    int myfield; 
    int myfield2; 
}; 

ben yazabilirim verilen. Bunu "mstct şeyi" beyanı olmadan/bir tane tahsis etmeden nasıl yapabilirim?

& <struct> yapısının her zaman yapının ilk alanının ilk baytını göstermediğini biliyorum, bunu daha sonra açıklayabilirim.

cevap

69

Standart offsetof() makrosuna (stddef.h içinde) ne dersiniz?

Düzenleme:

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

Tam olarak istediğimden değil, çünkü stddef.h'im yok, ama şu soruyu yanıtlıyor: #define offsetof (TYPE, ÜYE) ((size_t) & ((TYPE *) 0) -> ÜYE) – davenpcj

+3

Vay - hayır stddef.h? Sadece meraktan, ne kullandığını sorabilir miyim? –

+0

C99 standardında, bu yüzden yeni bir derleyici almanızı öneriyorum. – wnoise

8

Sağ, hangi (en azından ile offsetof makro kullanın: nedense mevcut offsetof() makro olmayabilir insanlar için, gibi bir şey kullanarak etkiyi elde edebilirsiniz

offsetof(struct mstct, myfield2) 
+0

offsetof(), ilk ANSI C89 standardından beri standart C/C++'daydı. Ciddi derecede eski bir şey kullanmadığınız sürece her derleyici buna sahip olmalıdır. Daha sonra bile çirkin döküm ve işaretçi aritmetiği kullanılarak bir araya getirilebilir. –

+0

Kabul - Bu makroları sağlamak için muhtemelen bir bir kukla sağlayacaktır. Plauger, "Standart C Kütüphanesi" ni sağlar ve taşınabilir olması gerekmediği sürece, sağlaması kolay bir başlıktır. –

+0

AFAIK, offsetof() * değil * çirkin döküm ve işaretçi aritmetiği değildir ... gibi bir şey: #define offsetof (type, field) ((char *) & (((type *) 0) -> alan) - (char *) 0) –

3

printf ("telafi:% d \ n", & ((mstct *) 0) GCC) C ve C++ kodu hem mevcuttur -> myfield2);

+1

'offsetof'un bunu daha okunabilir bir şekilde yapması dışında, genellikle LP64 sistemlerinde' ptrdiff_t' ''% d' ile yazdıramazsınız, çok büyük. –