如何证明 -> 在 int* pMember = &(pSomeType->SomeIntMember) 时不用于顺从;
How to prove -> is not used to deference when int* pMember = &(pSomeType->SomeIntMember);
在这个问题上:
asker 提出了一个关于#define offsetof(st, m)
((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
顺从 null(0( 指针的问题,并且没有段错误。
贾里德帕尔的回答指出:
上面使用了 -> 运算符,但不用于访问该值。 相反,它用于获取值的地址。这是一个 非宏代码示例,应该使其更清晰一些
SomeType *pSomeType = GetTheValue(); int* pMember = &(pSomeType->SomeIntMember);
第二行实际上不会导致取消引用(实现 依赖(。它只是返回 SomeIntMember 在 pSomeType 值。
我的问题是如何证明int* pMember = &(pSomeType->SomeIntMember);
只是将SomeIntMember的地址分配给pMember而不引用pSomeType。
有没有ISO C++标准?或者有什么方法?
编辑:
虽然我发布的问题关于c,但我想要c ++的答案,所以我标记了这个问题c ++。
如果 c++ 标准中有一些东西,那就更好了。
否则,我希望看到一些东西来证明JaredPar的结论,例如,xaxxon发布了程序集,或者特定的编译器如何实现。
如果答案成立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->x)
不是有效的指针,则p
会导致未定义的行为。
关于"offsetof"编辑,实现头文件中的代码不受语言规则的约束。它们可以包含魔术和非标准的不可移植代码。
正如 M.M 的回答所指出的,->
运算符是取消引用(如果操作数是指针(。关于这是否是取消引用的混淆可能源于内存访问的相关概念。
取消引用指针就是获取指向地址处的对象。或者更准确地说,给定一个指针p
类型为T*
,表达式*p
是T
类型的左值,指的是指向的对象。
内存访问是指发生读取或写入,分别对应于左值到右值的转换和分配。当不发生任何操作时,不会访问内存。
pSomeType->SomeIntMember // is defined to be...
(*pSomeType).SomeIntMember
*pSomeType
是SomeType
的左值,因此其成员SomeIntMember
是int
的左值。
然后它的地址被占用。没有发生左值到重值的转换,也没有发生赋值,因此没有内存访问,如@xaxxon的评论所示。
- EASTL矢量<向量<int>>连续的
- 如何证明 -> 在 int* pMember = &(pSomeType->SomeIntMember) 时不用于顺从;
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- C 字符串比较“祝您好运”&gt;“再见”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- C 操作员&gt;&gt;与突变器过载
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 是否需要使用 - &gt;运算符在C 中调用成员函数时
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- 错误c++visual studio c2227左侧'->;Init';必须指向类/结构/联合/泛型类型
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- ``这个''不能用this-&gt;指针变量
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 使用shared_ptr<字符串>转换为一个无序集合<字符串>
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾