【问题标题】:Do compilers avoid intermediate integral promotion or conversions?编译器是否避免中间积分提升或转换?
【发布时间】:2016-03-24 21:59:17
【问题描述】:

考虑这样一个类:

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 表达式中所需的类型?

【问题讨论】:

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

标签: c++ c++11 casting integer compiler-optimization


【解决方案1】:

似乎 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 castClang with direct reference to field

Gcc with castGcc with direct reference to field

虽然在稍微不同的情况下,Clang 执行 manage to optimize 调用 cast 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多