查看此代码:
#include <stdio.h>
unsigned short GetShort_With_Warning( unsigned long long val ) {
return *(unsigned short*)&val;
// mov ax,word ptr [val] // That's it. Elegance
}
unsigned short GetShort_Without_Warning( unsigned long long val ) {
unsigned short* shv = (unsigned short*)&val;
// lea eax,[val]
// mov dword ptr [shv],eax
return *shv;
// mov eax,dword ptr [shv]
// mov ax,word ptr [eax]
}
int main( void ) {
printf( "%04x\n", GetShort_With_Warning ( 0x101234ULL ) );
printf( "%04x\n", GetShort_Without_Warning( 0x101234ULL ) );
return 0;
}
这只是一个例子...
有两个功能可以实现相同的功能,但是一个功能会发出警告,而另一个功能则不会。汇编代码带有注释。可以确定“优雅”的决定没有发出警告吗?
它是用g ++编译的:
g++ -Wall -O3 -s -I. -c -o main.o main.cc
出现以下警告:
main.cc:4:28: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
return *(unsigned short*)&val;
^~~
我知道警告要说什么。
我知道使用当今的CPU能力,这种情况就没问题了。
反正... 我的问题是为什么警告不允许我优化代码?
答案 0 :(得分:4)
您“优化代码”的想法是基于一些信念,这些信念在实际C ++语言中没有任何基础。您制定了一套规则,将C ++代码转换为预期的机器代码时应遵循这些规则。但是实际上,这些规则在C ++中都不存在。那不是C ++的工作方式。
尤其是,您以某种方式提出了一个想法,即上述函数中使用的类型打孔的指针访问应允许您将unsigned long long
对象的一部分作为unsigned short
对象进行访问。但这不是真的。语言没有这种功能,而且从来没有。当目标类型是“字节”类型时,这种就地内存重新解释是可能的。但不是unsigned short
时。