The*_*ant 13 c pointers strict-aliasing
在这些评论用户@Deduplicator坚持认为,严格别名规则允许通过一个不兼容的类型的访问,如果任一混叠或混叠指针的是一个指针到字符的类型(合格或不合格,符号或无符号char *).所以,他的断言基本上都是这两个
long long foo;
char *p = (char *)&foo;
*p; // just in order to dereference 'p'
Run Code Online (Sandbox Code Playgroud)
和
char foo[sizeof(long long)];
long long *p = (long long *)&foo[0];
*p; // just in order to dereference 'p'
Run Code Online (Sandbox Code Playgroud)
符合并定义了行为.
但是,在我的阅读中,它只是第一种有效的形式,也就是说,当别名指针是指向char的指针时; 但是,在另一个方向上不能这样做,即当别名指针指向不兼容的类型(字符类型除外)时,别名指针为a char *.
所以,上面的第二个片段会有未定义的行为.
情况怎样?它是否正确?为了记录,我已经阅读了这个问题和答案,并且接受的答案明确指出了这一点
规则允许例外
char *.它总是假设char *其他类型别名.但是这不会起作用,没有假设你的结构别名为chars的缓冲区.
(强调我的)
你说这是无效的是正确的.正如你自己引用的那样(所以我不会在这里重新引用)保证有效的演员表只能从任何其他类型到char*.
另一种形式确实违反标准并导致未定义的行为.然而,作为一点奖励让我们讨论一下这个标准.
Chars,在每个重要的体系结构上是唯一允许完全未对齐访问的类型,这是由于读取字节指令必须处理任何字节,否则它们将是无用的.这意味着对char的间接读取将始终在我知道的每个CPU上有效.
然而,相反的方法将不适用,除非指针在大多数拱门上与8个字节对齐,否则无法读取uint64_t.
但是,有一个非常常见的编译器扩展,允许您从char转换到其他类型的正确对齐指针并访问它们,但这是非标准的.另请注意,如果将指向任何类型的指针强制转换为指向char的指针,然后将其强制转换,则保证结果指针等于原始对象.所以这没关系:
struct x *mystruct = MakeAMyStruct();
char * foo = (char *)mystruct;
struct x *mystruct2 = (struct mystruct *)foo;
Run Code Online (Sandbox Code Playgroud)
而mystruct2将等于mystruct.这也保证了struct根据需要正确对齐.
所以基本上,如果你想要一个指向char的指针和一个指向另一个类型的指针,总是将指针声明为另一个类型然后转换为char.或者甚至更好地使用联盟,这是他们基本上...
请注意,该规则有一个值得注意的例外.一些旧的malloc实现用于返回char*.始终保证此指针可成功转换为任何类型,而不会破坏别名规则.
| 归档时间: |
|
| 查看次数: |
478 次 |
| 最近记录: |