C++ 中的常量和编译器优化

2021-12-20 00:00:00 optimization compiler-construction c++

我已经阅读了关于 C++ 中常量正确性的所有建议,这很重要(部分)因为它有助于编译器优化您的代码.我从未见过关于编译器如何使用这些信息来优化代码的一个很好的解释,即使是好书也没有继续解释幕后发生的事情.

I've read all the advice on const-correctness in C++ and that it is important (in part) because it helps the compiler to optimize your code. What I've never seen is a good explanation on how the compiler uses this information to optimize the code, not even the good books go on explaining what happens behind the curtains.

例如,编译器如何优化声明为 const 的方法与未声明为但应该为 const 的方法.当你引入可变变量时会发生什么?它们会影响 const 方法的这些优化吗?

For example, how does the compiler optimize a method that is declared const vs one that isn't but should be. What happens when you introduce mutable variables? Do they affect these optimizations of const methods?

推荐答案

让我们忽略方法,只看 const 对象;编译器在这里有更多的优化机会.如果对象声明为 const,则 (ISO/IEC 14882:2003 7.1.5.1(4)):

Let's disregard methods and look only at const objects; the compiler has much more opportunity for optimization here. If an object is declared const, then (ISO/IEC 14882:2003 7.1.5.1(4)):

除了任何类成员声明mutable (7.1.1) 可以修改,任何尝试修改 const 对象在它的生命周期 (3.8) 导致未定义的行为.

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

让我们忽略可能具有可变成员的对象――编译器可以自由地假设对象不会被修改,因此它可以产生重要的优化.这些优化可以包括:

Lets disregard objects that may have mutable members - the compiler is free to assume that the object will not be modified, therefore it can produce significant optimizations. These optimizations can include things like:

  • 将对象的值直接合并到机器指令操作码中
  • 完全消除永远无法访问的代码,因为在编译时已知的条件表达式中使用了 const 对象
  • 如果 const 对象控制循环的迭代次数,则循环展开

请注意,此内容仅适用于实际对象为 const 的情况 - 它不适用于通过 const 指针或引用访问的对象,因为这些访问路径可能导致非 const 的对象(甚至可以很好地定义更改对象虽然是常量指针/引用,只要实际对象是非常量的,并且你抛弃了对象访问路径的常量性).

Note that this stuff applies only if the actual object is const - it does not apply to objects that are accessed through const pointers or references because those access paths can lead to objects that are not const (it's even well-defined to change objects though const pointers/references as long as the actual object is non-const and you cast away the constness of the access path to the object).

在实践中,我认为没有编译器可以对所有类型的 const 对象执行任何重要的优化.但是对于原始类型(整数、字符等)的对象,我认为编译器在优化方面可能非常积极这些物品的使用.

In practice, I don't think there are compilers out there that perform any significant optimizations for all kinds of const objects. but for objects that are primitive types (ints, chars, etc.) I think that compilers can be quite aggressive in optimizing the use of those items.

相关文章