2009-06-18 17 views
0

我想要获取结构中特定成员的大小。C:更好的方式来做sizeof(((SomeStruct *)0) - > some_member)?

sizeof(((SomeStruct *) 0)->some_member)适合我,但我觉得可能有更好的方法来做到这一点。

我可以#define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM)然后使用SIZEOF_ELEM(SomeStruct, some_member),但我想知道是否已经有更好的内置。

我的具体用例是在hsc2hs(Haskell C绑定)中。

pokeArray (plusPtr context (#offset AVFormatContext, filename)) . 
    take (#size ((AVFormatContext *) 0)->filename) . 
    (++ repeat '\NUL') $ filename 
+2

这种方法有什么问题?这很好。标准offsetof()宏的工作方式相同。 – qrdl 2009-06-18 19:40:58

回答

5

如果你不能保证你有一个取消引用的变量,你得到的是干净的。 (如果可以的话,当然可以使用sizeof(var.member)sizeof(ptr->member),但是在需要编译时常量的情况下,这将不起作用。)

很久很久以前(大约在1990年) ,我遇到了一个编译器,它使用基地址0定义了'offsetof',并且它崩溃了。我通过盗号<stddef.h>来解决这个问题,使用1024而不是0.但是你现在不应该遇到这样的问题。

3

我相信你已经在那里得到了正确的解决方案。你可以挖掘你的stddef.h并查找offsetof是如何定义的,因为它做了一个非常类似的事情。

请记住,由于填充,成员的大小和该成员与下一个成员之间的偏移量之间可能存在差异。

3

在C++中,您可以执行sizeof(SomeStruct :: some_member),但这是c,并且您没有范围解析运算符。就我所知,你写的和写的一样好。

2

微软已经在他们的头下列操作之一:

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

我认为没有理由做任何不同。

他们有相关的宏:

RTL_SIZEOF_THROUGH_FIELD() 
RTL_CONTAINS_FIELD() 

和俏皮:

CONTAINING_RECORD() 

这有助于实现在传统的C泛型列表,而不必要求连接字段是在结构的开始。有关详细信息,请参阅此Kernel Mustard article

相关问题