为什么警告会阻止我们编写优化的程序?

时间:2018-07-24 21:04:23

标签: c++ casting g++ warnings

查看此代码:

#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能力,这种情况就没问题了。

反正... 我的问题是为什么警告不允许我优化代码?

1 个答案:

答案 0 :(得分:4)

您“优化代码”的想法是基于一些信念,这些信念在实际C ++语言中没有任何基础。您制定了一套规则,将C ++代码转换为预期的机器代码时应遵循这些规则。但是实际上,这些规则在C ++中都不存在。那不是C ++的工作方式。

尤其是,您以某种方式提出了一个想法,即上述函数中使用的类型打孔的指针访问应允许您将unsigned long long对象的一部分作为unsigned short对象进行访问。但这不是真的。语言没有这种功能,而且从来没有。当目标类型是“字节”类型时,这种就地内存重新解释是可能的。但不是unsigned short时。