c++ - 如何在没有运行时成本的情况下基于断言指导 GCC 优化?

标签 c++ gcc optimization assert compiler-optimization

我的代码中使用了一个在 Debug模式下使用的宏:

#define contract(condition) \
    if (!(condition)) \
        throw exception("a contract has been violated");

...但处于 Release模式:

#define contract(condition) \
    if (!(condition)) \
        __builtin_unreachable();

这对 assert() 的作用是,在发布版本中,由于 UB 传播,编译器可以大量优化代码。

例如,使用以下代码进行测试:

int foo(int i) {
    contract(i == 1);
    return i;
}

// ...

foo(0);

... 在 Debug模式下抛出异常,但在 Release模式下为无条件 return 1; 生成程序集:

foo(int):
        mov     eax, 1
        ret

条件以及依赖它的所有内容都已优化。

我的问题出现在更复杂的条件下。当编译器无法证明条件没有副作用时,它不会对其进行优化,与不使用合约相比,这是一种运行惩罚。

有没有办法表示合约中的条件没有副作用,从而总是优化出来?

最佳答案

Is there a way to express that the condition in the contract has no side effect, so that it is always optimized out?

不太可能。

众所周知,您不能将大量断言转化为假设(通过 __builtin_unreachable)并期望得到好的结果(例如 John Regehr 的 Assertions Are Pessimistic, Assumptions Are Optimistic)。

一些线索:

  • CLANG,虽然已经拥有 __builtin_unreachable 内在函数,但引入了 __builtin_assume正是为了这个目的。

  • N4425 - Generalized Dynamic Assumptions (*) 指出:

    GCC does not explicitly provide a general assumption facility, but general assumptions can be encoded using a combination of control flow and the __builtin_unreachable intrinsic

    ...

    The existing implementations that provide generic assumptions use some keyword in the implementation­reserved identifier space (__assume, __builtin_assume, etc.). Because the expression argument is not evaluated (side effects are discarded), specifying this in terms of a special library function (e.g. std::assume) seems difficult.

  • 指南支持库(GSL,由 Microsoft 托管,但绝不是 Microsoft 特定的)“仅”具有以下代码:

    #ifdef _MSC_VER
    #define GSL_ASSUME(cond) __assume(cond)
    #elif defined(__clang__)
    #define GSL_ASSUME(cond) __builtin_assume(cond)
    #elif defined(__GNUC__)
    #define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable())
    #else
    #define GSL_ASSUME(cond) static_cast<void>(!!(cond))
    #endif
    

    并指出:

    // GSL_ASSUME(cond)
    //
    // Tell the optimizer that the predicate cond must hold. It is unspecified
    // whether or not cond is actually evaluated.
    

<子> *) 论文 rejected :EWG 的指导是在提议的契约(Contract)设施内提供功能。

关于c++ - 如何在没有运行时成本的情况下基于断言指导 GCC 优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44054078/

相关文章:

c++ - 写入文件时由 delete[] 引起的段错误

c++ - 围绕函数调用解析的混淆

c++ - "vperm v0,v0,v0,v17"和未使用的 v0 有什么作用?

c++ - 我必须依赖编译器 NRVO 吗?

javascript - 动态注入(inject) javascript 文件 - 为什么大多数示例附加到头部?

c++ - 使用特征删除零列或行

c++ - 调用 `strcat` 并能够将较大的字符串存储到较小的字符串中?

C编程; GCC 在运行时崩溃

c - 使用 -std=c99 的隐式声明

mongodb - 如何在没有竞争条件的情况下使用 mongodb 实现有序数组?