Hacker News new | past | comments | ask | show | jobs | submit login

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

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.




It'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


Fascinating. 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?


I tried gcc, clang, msvc, and icc. They all generated the load and either an add or an inc. https://godbolt.org/z/han78n9zM If we define `f` to const_cast away the const and add 10: 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 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

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.


I don't understand what is defeated in your example.


I edited to add a godbolt link, but repeating here: 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`.


Isn'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.


Unfortunately, `x` does escape, merely because we initialized it via assigning to it from a non-const.


Interesting point! That's my understanding as well.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: