3 ms·
One of the escape analysis examples in the article got me thinking. Turns out this is one of those cases where marking a local variable const _does_ result in d
by IAmLiterallyAB 3y ago
One of the escape analysis examples in the article got me thinking. Turns out this is one of those cases where marking a local variable const _does_ result in different code.
See this godbolt example https://godbolt.org/z/nbzd59E33 https://godbolt.org/z/nbzd59E33
As I understand it, performing a const_cast itself isn't undefined behavior, which is why the compiler cannot assume function f doesn't modify the local. However, if we mark the local variable as const, the compiler is able to assume no modification will occur (because that would be undefined) and optimize the return.
- levzettelin 3y agoInteresting point! That's my understanding as well.
- celrod 3y agoIt's unfortunately easy to defeat this, e.g. int y = 42; const int x = y; is enough, even though `x` is still a `const` local variable. https://godbolt.org/z/7vre49xb1 https://godbolt.org/z/7vre49xb1
- jenadine 3y agoI don't understand what is defeated in your example.
- celrod 3y agoI edited to add a godbolt link, but repeating here: https://godbolt.org/z/7vre49xb1 https://godbolt.org/z/7vre49xb1 In my example, even though `x` is a `const` local, the assembly still shows that it reloads `x` and adds `1` if we assign to it from a non-const local `y`.
- gameman144 3y agoIsn't that expected since 'y' is still non-const though? In your example, I'd expect 'x' to not escape, since a const-cast of it is undefined.
- celrod 3y agoUnfortunately, `x` does escape, merely because we initialized it via assigning to it from a non-const.
- IAmLiterallyAB 3y agoFascinating. Does anyone know why x escapes here? Is it an optimization miss? Because to my untrained eye modifying x should still be undefined behavior. Does the way x is initialized make it not "const-y" enough?
- celrod 3y agoI tried gcc, clang, msvc, and icc. They all generated the load and either an add or an inc. https://godbolt.org/z/han78n9zM https://godbolt.org/z/han78n9zM If we define `f` to const_cast away the const and add 10: https://godbolt.org/z/1dso8ojWG https://godbolt.org/z/1dso8ojWG all the compilers agree that we should get 53. However, make `y` const, so we have const int y = 42; const int x = y; and now modifying x suddenly becomes undefined behavior, and x + 1 returns 43 https://godbolt.org/z/cqbGasrMM https://godbolt.org/z/cqbGasrMM Similar to how the original assembly showed making `y` const removed the reload and increment/+1 of x. So, it seems that all these compilers agree that modifying `x` is undefined behavior if `y` is const, but is defined if `y` is mutable. I am not sure why this is. I may have misunderstood, but I didn't get the impression this should be the case from reading: https://en.cppreference.com/w/cpp/language/cv https://en.cppreference.com/w/cpp/language/cv My best guess is that for some reason, `x` is a constant object only if initialized itself via a constant object. But I couldn't find anything saying that is the case. I asked on the #learn channel of cppslack.