1

我想获取结构中特定成员的大小。

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
4

4 回答 4

5

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

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

于 2009-06-18T19:51:44.080 回答
3

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

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

于 2009-06-18T19:52:37.103 回答
3

在 C++ 中,您可以执行 sizeof(SomeStruct::some_member),但这是 c,您没有范围解析运算符。就我所知,你写的已经写得很好了。

于 2009-06-18T19:53:08.507 回答
3

Microsoft 在其标题之一中包含以下内容:

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

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

他们有相关的宏:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

和漂亮的:

CONTAINING_RECORD() 

这有助于在直接 C 中实现通用列表,而不必要求链接字段位于结构的开头。有关详细信息,请参阅这篇Kernel Mustard 文章

于 2009-06-18T20:03:38.033 回答