att*_*rri 0 c strict-aliasing undefined-behavior
我知道违反严格别名规则是根据C标准的未定义行为.请不要告诉我这是UB,没有什么可谈的.
我想知道下面的代码是否有编译器没有预期的行为(由我在下面定义).
假设的大小float和int为4个字节,并且大端机.
float f = 1234.567; /* Any value here */
unsigned int u = *(unsigned int *)&f;
Run Code Online (Sandbox Code Playgroud)
我在英语单词中的预期行为是"获取float存储的四个字节并按int 原样放入".在代码中它将是这个(我认为这里没有UB):
float f = 1234.567; /* Any value here */
unsigned char *p = (unsigned char *)&f;
unsigned int u = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
Run Code Online (Sandbox Code Playgroud)
我也欢迎实际和具体的例子,为什么,除了按照标准的UB,编译器会有我认为是意想不到的行为.
在大多数编译器中,它会按照您的期望执行,直到优化程序决定使用死代码消除或将赋值移动到f.
这使得基本上不可能测试任何给定的编译器是否总是按照您的期望执行 - 它可能适用于一个特定的程序,但稍微不同的可能会失败.严格别名规则基本上只是告诉编译器实现者"你可以通过假设它们永远不会别名来相当自由地重新排列和消除这些东西".当执行会导致此代码失败的事情没有用时,优化器可能不会,因此您不会看到问题.
最重要的是,谈论"哪些编译器将会起作用" 是没有用的,因为如果某些看似无关的内容发生变化,它们可能会在将来突然停止工作.