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

Do compilers avoid intermediate integral promotion or conversions?

考虑 class 比如:

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;
}

你可以检查编译好的程序集并比较它们:

Clang with cast vs Clang with direct reference to field

Gcc with cast vs Gcc with direct reference to field

尽管在稍微不同的情况下,Clang 会 manage to optimize 调用转换函数。