【问题标题】:What does `((t*)0)->f)` do in C code?`((t*)0)->f)` 在 C 代码中做了什么?
【发布时间】:2017-11-04 22:47:21
【问题描述】:

我在 C (Linux) 代码 here 中看到了以下奇怪类型的宏:

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

((t*)0)->f) 是做什么的?

它是如何工作的?

【问题讨论】:

  • 你知道cdecl.org 吗? (虽然不是这个问题的解决方案)
  • 你知道任何 C 语言吗?你知道-> 是做什么的吗?
  • 企图向自己的脚开枪?
  • Note C 将struct 部分称为“成员”,而不是“字段”。

标签: c linux macros sizeof


【解决方案1】:

这个东西正如名字所暗示的那样 - 提供结构字段的大小。

它首先将 0(这是一个任意地址)转换为结构类型的指针。

然后它->(通过指针访问)获取该字段并将sizeof应用于它。

非常简单!

【讨论】:

  • 0 不是任意的;它是一个空指针常量,所以(t*)0 是一个空指针。
  • 值得注意的是,sizeof 运算符不会评估它所使用的值,否则你会得到未定义的行为。如果是 UB,即使是这样也是一个争论的问题......
  • @melpomeme。在这种情况下,给指针一个名字并不会降低它的任意性。任何其他值也可以。此外,从技术上讲,NULL 是一个依赖于实现的值,不需要为零。
  • @MadPhysicist C standard 6.3.2.3p3 我并不是说 NULL 指针应该有一个值 0(指针甚至不需要是整数),我只是说将 0 转换为指针类型会给出 NULL指针常量。
  • @MadPhysicist 在你指向的链接中,看看这个comment
【解决方案2】:

它会按照罐头上的说明进行操作,例如 Marcus Müller explains。如果您想知道为什么要打扰它,为什么我们不能直接使用sizeof(type_of_field),然后考虑一下:

struct foo {
  struct {
    int a;
    float b;
  } bar;
};

我们不能命名type_of_bar,因为对于程序员来说它没有名字。但无论如何,宏允许我们通过变通方法获取字段大小。

【讨论】:

    【解决方案3】:

    因为 sizeof 是在编译时计算的(除了可变长度数组,这里不是这种情况)它的参数不会在运行时计算。因此可以强制转换 NULL 指针,因为它仅用于指示正​​在计算其大小的字段。

    【讨论】:

    • 这是关键信息,没有被提及。
    • 代码中其实有一个假设。一般情况下并非如此。
    猜你喜欢
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 2016-02-14
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多