In C++, can the value of a const &
change?
Well, of course it cannot change, can it? That's what const
means. Moreover, listen to Stroustrup:
A
const
lvalue reference refers to a constant, which is immutable from the point of view of the user of the reference.
But what about this?
#include <iostream>
int main() {
int a = 0;
const int& r = a;
const int old_r = r;
++a;
const int new_r = r;
std::cout
<< "old_r == " << old_r
<< " but new_r == " << new_r << std::endl;
return 0;
}
On my machine, this outputs, old_r == 0 but new_r == 1
.
That gets to my real question. In the above code, look at the line
const int new_r = r;
Insofar as
&new_r
is extracted neither on this line nor elsewhere in the code andvolatile
,does anything prevent an optimizing compiler from merging old_r
and new_r
into a single constant object, treating the line as though it read as follows?
const int& new_r = old_r;
I ask because, as far as I know, if the compiler did so optimize, that might alter the behavior. The program might output, old_r == 0 but new_r == 0
.
RELATED QUESTIONS
The most nearly related existing question I find is this one:
The following are also related but, unlike the present question, involve casts:
See also N4659 (draft C++17 standard), sect. 10.1.7.1, "The cv-qualifiers."
The quote of Stroustrup at the top of the question comes from sect. 7.7.2 of The C++ Programming Language, 4th ed. Of course, no author can write every sentence perfectly in a thousand-page book; yet perhaps Stroustrup is clear and I have merely read him wrong. Nevertheless, you might see why the sentence has confused me. This is why I have asked.
In C++, can the value of a
const &
change?
Yes, but not through that reference (ignoring mutable
fields).
void foo(const int& c, int& mut) {
std::cout << c << " ";
++mut; // changes `c` if &c == &mut
std::cout << c << std::endl;
}
and
int a = 42;
foo(a, a); // 42 43
does anything prevent an optimizing compiler from merging old_r and new_r into a single constant object, treating the line as though it read as follows?
The as-if rule allows compiler to optimize if visible side effect are the same,
which is not the case here. So your "proposed merge of variable" in your code cannot be done fortunately.