Does const allow for (theoretical) optimization here?

↘锁芯ラ 提交于 2019-12-03 17:28:51

问题


Consider this snippet:

void foo(const int&);

int bar();

int test1()
{
    int x = bar();
    int y = x;
    foo(x);
    return x - y;
}

int test2()
{
    const int x = bar();
    const int y = x;
    foo(x);
    return x - y;
}

In my understanding of the standard, neither x nor y are allowed to be changed by foo in test2, whereas they could be changed by foo in test1 (with e.g. a const_cast to remove const from the const int& because the referenced objects aren't actually const in test1).

Now, neither gcc nor clang nor MSVC seem to optimize test2 to foo(bar()); return 0;, and I can understand that they do not want to waste optimization passes on an optimization that only rarely applies in practice.

But am I at least correct in my understanding of this situation, or am I missing some legal way for x to be modified in test2?


回答1:


The standard says in [dcl.type.cv]:

Except that any class member declared mutable […] can be modified, any attempt to modify […] a const object […] during its lifetime […] results in undefined behavior.

It is also not possible to make this defined by ending the lifetime of the object prematurely, according to [basic.life]:

Creating a new object within the storage that a const complete object with […] automatic storage duration occupies, or within the storage that such a const object used to occupy before its lifetime ended, results in undefined behavior.

This means that the optimization of x - y to zero is valid because any attempt to modify x in foo would result in undefined behavior.

The interesting question is if there is a reason for not performing this optimization in existing compilers. Considering that the const object definition is local to test2 and the fact is used within the same function, usual exceptions such as support for symbol interposition do not apply here.




回答2:


The const helps very little to basically nothing for optimization. The compiler basically needs a global view on the code to decide if variables are truly constant or not, and the compiler will determine this regardless of the const modifiers. Consider this code (e.g. in godbolt.org)

void foo(const int& v) { const_cast<int&>(v) = 6; }
const int bar() { return 9; }
int main() {
     const int a = bar();
     const int b = a;
     foo(a);
     return a-b;
}

which will result for -O3 in gcc8.3 and clang7 to the very correct and optimal (even with the additional not-essential const_cast that causes undefined behavior):

foo(int const&):                              # @foo(int const&)
        mov     dword ptr [rdi], 6
        ret
bar():                                # @bar()
        mov     eax, 9
        ret
main:                                   # @main
        mov     eax, -3
        ret

and what is important: this is identical if you replace all const int by just int. Thus, it is not the const that helps the compiler, it is global code view and analysis.

In the end let me quote this very interesting GotW page from Herb Sutter http://www.gotw.ca/gotw/081.htm which as I see also started the whole issue.

Thus, const remains a feature predominately for programmers. Compilers are smarter than us and don't trust us anyway ;-)

And a final remark: optimization is in almost all cases a feature of the compiler and not of the language. There are some exceptions from that, e.g. copy elision, but the question of this issue is not one of them.



来源:https://stackoverflow.com/questions/55128512/does-const-allow-for-theoretical-optimization-here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!