【问题标题】:Where can I learn about compilers and assert optimization?我在哪里可以了解编译器和断言优化?
【发布时间】:2021-10-19 10:36:38
【问题描述】:

我们最近发现编译器(对我们来说是 GCC)可以结合开发人员设置的断言优化一些代码。

此代码示例:

#include <cassert>
int getBatteryLevel(){
    return 0;
}
int process(int level);
int main() {
    [[maybe_unused]] const auto level = getBatteryLevel();
    assert(level > 0);
    process(level);
}

即使process 没有实现,也会与-O2 链接。没有优化就不会链接。

这是否记录在任何地方?

【问题讨论】:

  • 不确定这是否在任何地方明确记录。只是编译器注意到没有办法调用process。请注意,当您将断言替换为if (level == 0) std::terminate(); 时,您会得到相同的效果。 godbolt.org/z/sW6sod7jb 所以这不是特定于 assert
  • 这是一个有趣的观察,但恐怕答案(几乎?)微不足道:链接器仅在实际调用函数时才抱怨缺少定义。当没有打开优化时,编译器不会费心删除死代码
  • 我相信这应该回答为什么允许这样做:stackoverflow.com/questions/15718262/…
  • 您的示例现在完全不同了,但编译器仍然可以看到程序在调用函数之前终止。
  • fwiw,同样在您的新示例中,您可以将 assert 替换为对 terminate 的等效调用以查看相同的效果:godbolt.org/z/v5aEq6M4Y

标签: c++ gcc optimization compiler-construction assert


【解决方案1】:

这是否记录在任何地方?

优化的文档不是很详尽。这里可能用到的优化是“内联扩展”、“常量折叠”和“死代码消除”。

在哪里可以了解编译器

书籍是一个很好的起点,除非您打算从头开始发明计算。学术论文也可以包含很好的信息,但是过滤掉不相关的东西,找出所需的初步知识可能是很多工作。此外,每单位信息的成本往往很高。


附:如果您没有定义 odr-used 的函数,则该程序是格式错误的。语言实现可以接受格式错误的程序,但不是必须的。通常,他们需要诊断此类错误,但这种特殊情况是不需要诊断的实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 2011-09-15
    • 2010-10-01
    • 2014-08-29
    • 1970-01-01
    • 2010-10-30
    • 2011-04-06
    相关资源
    最近更新 更多