C:更好的方法来执行 sizeof(((SomeStruct *) 0)->some_member)?

发布于 2024-07-25 03:23:53 字数 496 浏览 8 评论 0原文

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

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

I want to get the size of a specific member in a struct.

sizeof(((SomeStruct *) 0)->some_member) works for me but I feel like there might be a nicer way to do it.

I could #define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM) and then use SIZEOF_ELEM(SomeStruct, some_member), but I wonder whether there is already something better built-in.

My specific use-case is in hsc2hs (Haskell C bindings).

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼眸印温柔 2024-08-01 03:23:53

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

很久很久以前(大约 1990 年),我遇到了一个使用基地址 0 定义“offsetof”的编译器,它崩溃了。 我通过修改 使用 1024 而不是 0 来解决这个问题。但是您现在不应该遇到此类问题。

What you've got is about as clean as it gets if you can't guarantee you have a variable to dereference. (If you can, then use just sizeof(var.member) or sizeof(ptr->member), of course, but this won't work in some contexts where a compile-time constant is needed.)

Once upon a long, long time ago (circa 1990), I ran into a compiler that had 'offsetof' defined using the base address 0, and it crashed. I worked around the problem by hacking <stddef.h> to use 1024 instead of 0. But you should not run into such problems now.

ま柒月 2024-08-01 03:23:53

微软在其标题之一中有以下内容:

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

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

它们有相关的宏:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

和漂亮的:

CONTAINING_RECORD() 

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

Microsoft has the following in one of their headers:

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

I see no reason to do any different.

They have related macros for:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

and the nifty:

CONTAINING_RECORD() 

which helps implement generic lists in straight C without having to require that link fields be at the start of a struct. See this Kernel Mustard article for details.

夏有森光若流苏 2024-08-01 03:23:53

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

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

I believe you've already got the correct solution there. You could dig up your stddef.h and look for how offsetof is defined, since it does a very similar thing.

Remember that there may well be a difference between the sizeof a member and the difference between the offsetofs of that member and the next one, due to padding.

不离久伴 2024-08-01 03:23:53

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

In C++ you could do sizeof(SomeStruct::some_member), but this is c and you have no scope resolution operator. What you've written is as good as can be written, as far as I know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文