c - 为什么非常量 offsetof 表达式有效?

标签 c offsetof

为什么这样做:

#include <sys/types.h>
#include <stdio.h>
#include <stddef.h>

typedef struct x {
    int a;
    int b[128];
} x_t;


int function(int i)
{
  size_t a;

  a = offsetof(x_t, b[i]);

  return a;
}

int main(int argc, char **argv)
{
    printf("%d\n", function(atoi(argv[1])));
}

如果我没记错 offsetof 的定义,它是一个编译时构造。使用“i”作为数组索引会产生非常量表达式。我不明白编译器如何在编译时评估表达式。 为什么不将此标记为错误?

最佳答案

C 标准不要求它工作,但它可能在某些 C 实现中工作,因为 offsetof(type, member) 扩展为如下内容:

type t; // Declare an object of type "type".
char *start = (char *) &t; // Find starting address of object.
char *p = (char *) &t->member; // Find address of member.
p - start; // Evaluate offset from start to member.

我将上面的内容分成几个部分来显示基本逻辑。 offsetof 的实际实现会有所不同,可能使用依赖于实现的功能,但核心思想是从对象内成员的地址中减去虚构或临时对象的地址,这会导致偏移。它旨在为成员工作,但作为一个意想不到的效果,它也适用于(在某些 C 实现中)结构中的数组元素。

它适用于这些元素,因为用于查找成员地址的构造也适用于查找数组成员的元素地址,并且指针的减法以自然的方式工作。

关于c - 为什么非常量 offsetof 表达式有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19505280/

相关文章:

c++ - 将字段的偏移量作为模板参数传递给该字段

c++ - 从数据成员中获取非 POD 对象的地址,该数据成员是一次性嵌套类

c - 在 cmocka 单元测试框架的上下文中解释 mock()

c - 字符串和指针

c - 'ap' 在 C 示例中代表什么?

c - MIPS 堆栈指针

c++ - 对于 C++17 中的非标准布局类, `offsetof` 为 "conditionally-supported"是什么意思?

c - 如何将字节内存从内核模块映射到用户空间应用程序?

c++ - 如何找到结构字段占用的空间以及它与下一个字段之间的填充?