这是在stddef.h中的一系列宏之一。
#define offsetof(s,m) (size_t)&(((s *)0)->m)
What does (s *)0 mean?
#define offsetof(s,m) (size_t)&(((s *)0)->m)
What does (s *)0 mean?
这是一种写法来表示一个类型为指向s的指针
的NULL
指针。通过获取一个地址为0的s
成员m
的地址,可以得到在s
内的m
偏移量。
((s *)0)->m
不会引发未定义行为吗? - Nawazstddef.h
。我知道这并不能证明什么,但它表明了这种技术是多么被接受。我非常确定这是合法的,因为正如 @comonad 所说,我们所做的只是计算地址:我们并不会用它做任何事情。 - Ernest Friedman-Hill这是一种类型转换,将0
转换为s的指针
。
static_cast
或其中一个 C++ 强制转换。 - Shoes
。在这种情况下,s
是宏的一个参数,希望是类型名称。s
的指针,并将其值设置为零(null)。s在这里应该是一个类型名,比如int
,因此(s*)0
基本上是将0
强制转换为指针类型。
0
不仅是整数零,还是空指针。因此,((S*)0)
将空指针转换为指向 s
的指针(其中 s
可能是一个结构体)。
offsetof(type,member)
的行为由 C++ 标准(C++11 18.2/4)定义,但仅当type
是一个标准布局类型且member
引用非静态数据成员时。这个特定的offsetof
实现依赖于不被标准定义而是由具体的 C++ 实现定义的行为。换句话说,在您的代码中使用offsetof
是完全可以的,但像这个offsetof
实现所做的那样在您的代码中解引用空指针是不可移植的。 - Casey