当问到C语言中常见的未定义行为时,人们有时会提到严格的混叠规则。 他们在谈论什么?
当前回答
严格的混叠不只是指指针,它也影响引用,我为boost开发者wiki写了一篇关于它的论文,它很受欢迎,我把它变成了我的咨询网站上的一个页面。它完全解释了它是什么,为什么它让人们如此困惑,以及如何应对它。严格的混叠白皮书。它特别解释了为什么联合对于c++来说是危险的行为,以及为什么使用memcpy是唯一可以在C和c++之间移植的修复程序。希望这对你有帮助。
其他回答
作为Doug T.已经写过的附录,在这里 是一个简单的测试用例,可能会触发GCC:
check.c
#include <stdio.h>
void check(short *h,long *k)
{
*h=5;
*k=6;
if (*h == 5)
printf("strict aliasing problem\n");
}
int main(void)
{
long k[1];
check((short *)k,k);
return 0;
}
编译gcc -O2 -o check check.c。 通常(我尝试过的大多数gcc版本)这会输出“严格的混叠问题”,因为编译器假设“h”不能与“check”函数中的“k”地址相同。因此,编译器会优化if (*h == 5),并始终调用printf。
对于那些感兴趣的人,这里有x64汇编代码,由gcc 4.6.3生成,运行在ubuntu 12.04.2的x64上:
movw $5, (%rdi)
movq $6, (%rsi)
movl $.LC0, %edi
jmp puts
所以if条件从汇编代码中完全消失了。
严格的混叠不只是指指针,它也影响引用,我为boost开发者wiki写了一篇关于它的论文,它很受欢迎,我把它变成了我的咨询网站上的一个页面。它完全解释了它是什么,为什么它让人们如此困惑,以及如何应对它。严格的混叠白皮书。它特别解释了为什么联合对于c++来说是危险的行为,以及为什么使用memcpy是唯一可以在C和c++之间移植的修复程序。希望这对你有帮助。
通过指针强制转换(而不是使用联合)的类型双关是打破严格混叠的一个主要例子。
严格的混叠是不允许不同的指针类型指向相同的数据。
本文将帮助您全面详细地理解这个问题。
从技术上讲,在c++中,严格的混叠规则可能永远都不适用。
注意indirection(*运算符)的定义:
一元*运算符执行间接操作:它所对应的表达式 是指向对象类型的指针,还是指向对象类型的指针 函数类型,结果是指向对象或的左值 表达式所指向的函数。
同样来自glvalue的定义
glvalue是一个表达式,其求值决定的标识 一个对象,(…剪)
因此,在任何定义良好的程序跟踪中,glvalue都指向对象。所以所谓的严格混叠规则并不适用。这可能不是设计师想要的。