提问者提出关于 #define offsetof(st, m) \
((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
的问题遵循 null(0) 指针并且没有段错误。
The -> operator is used above but it's not used to access the value. Instead it's used to grab the address of the value. Here is a non-macro code sample that should make it a bit clearer
SomeType *pSomeType = GetTheValue(); int* pMember = &(pSomeType->SomeIntMember);
The second line does not actually cause a dereference (implementation dependent). It simply returns the address of SomeIntMember within the pSomeType value.
我的问题是如何证明int* pMember = &(pSomeType->SomeIntMember);
只是将 SomeIntMember 的地址分配给 pMember,而不引用 pSomeType。
有没有iso c++标准?或者有什么方法吗?
编辑:
虽然我发布的问题是关于c的,但我想要c++的答案,所以我把这个问题标记为c++。
如果有c++标准的就更好了。
否则,我希望看到一些东西来证明 JaredPar 的结论,例如 xaxxon发布了 assembly ,或者具体的编译器是如何实现的。
如果答案成立 int* pMember = &(pSomeType->SomeIntMember);
确实尊重 pSomeType,那么为什么 offsetof 的实现(#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
)有效?
更新:
感谢所有的评论和回答,现在我明白了 #define offsetof(st, m) ((size_t) ( (char*)&((st*)(0))->m - (char)0))
是 c 中的实现之一,而不是 c++ 中的实现。
另外,我找到了 msvc 的实现,#define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
,但对我来说有点复杂,有人可以表达一下吗?提前致谢。
最佳答案
->
运算符确实会导致取消引用。 a -> b
被定义为 (*a).b
,如果 a
是一个指针。
如果人们声称这不是取消引用,那么他们要么错了,要么使用了“取消引用”一词的一些非标准含义。
在 C++ 标准中,*
的正式名称是间接运算符。 “取消引用”一词不用作动词;相反,该标准表示将 *
运算符应用于指针会产生一个左值,指定所指向的对象。
p
不是有效指针,&(p->x)
会导致未定义的行为。
关于“offsetof”编辑,实现头文件中的代码不受语言规则的约束。它们可以包含神奇的和非标准的不可移植代码。
关于c++ - 如何证明 -> 当 int* pMember = &(pSomeType->SomeIntMember) 时不用于推导;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45396482/