C++ 编译器是否避免中间整数升级或转换?

C++ 编译器是否避免中间整数升级或转换?,c++,c++11,casting,integer,compiler-optimization,C++,C++11,Casting,Integer,Compiler Optimization,考虑这样一个类: struct mystruct { constexpr operator char() {return x;} signed char x; }; 以及类似以下的操作: mystruct m; m.x = /* something at runtime */ int i = 3 * m + 45ULL * m; 编译器是否能够跳过对char的临时转换,并直接将m转换为3*m+45ULL*m表达式中所需的类型?似乎GCC 5.3.0版能够优化对cast函数的

考虑这样一个类:

struct mystruct 
{
    constexpr operator char() {return x;}
    signed char x;
};
以及类似以下的操作:

mystruct m;
m.x = /* something at runtime */
int i = 3 * m + 45ULL * m;

编译器是否能够跳过对
char
的临时转换,并直接将
m
转换为
3*m+45ULL*m
表达式中所需的类型?

似乎GCC 5.3.0版能够优化对cast函数的调用,而Clang 3.7没有那么智能

对于这段代码:

struct mystruct 
{
    constexpr operator char() const {return x;}
    signed char x;
} m;

void func(const int num) {
  m.x = num*2;
  int i = 3 * m + 45ULL * m;
}
您可以检查已编译的程序集并比较它们:

vs

vs


虽然情况略有不同,但Clang会调用cast函数。

编译到汇编并找出答案!这取决于您使用的编译器和标志。但是如果
返回x怎么办?x*10:10或更复杂的东西。我不认为编译器通常会跳过到
char
的中间转换,因为毕竟这是一个函数调用,它可以做很多复杂的事情,因此在不知道中间值的情况下可能无法计算最终值,其中还包括由于较小类型而导致的截断。编译器尽可能最好地实现语言规则。如果结果与应用规则推断的结果不匹配,编译器将被破坏。您能否解释一下“编译器是否能够跳过临时转换为char并直接将m转换为3*m+45ULL*m表达式中所需的类型?”的意思?没有临时转换,
3*m
3*m.x
完全相同——除非我们在一个系统上,eplain char是无符号的
signed char
由于整数提升而提升为
int
(这些是
*
操作符的语言规则)