问题
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
- the address
&new_r
is extracted neither on this line nor elsewhere in the code and - the code has nothing
volatile
,
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:
- (C language) Can const be changed? (See especially the linked question's point no. 1.)
The following are also related but, unlike the present question, involve casts:
- Changing the value of a const
- Two different values at the same memory address
- Modifying constant object
- Changing the value of const variable [duplicate]
- (C language) Accessing a non-const through const declaration
- (C language) Can we modify the value of a const variable?
- (C language) Const variable value is changed by using a pointer
- (C language) Confusion regarding modification of const variable using pointers
- (C language) Weird Behaviour with const_cast [duplicate]
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.
回答1:
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.
回答2:
In C++, can the value of a const & change?
Yes, this is perfectly legal. Taking a const&
to some variable doesn't stop that variable from being able to be modified, it just means you can't modify the variable through the reference. That means
int a = 42;
int const& b = a;
++a;
std::cout << a << " " << b;
will print
43 43
Had I tried to do
++b;
though that would be a compiler error as b
's access to the value is const
and ++
is a non const operation.
回答3:
Well, of course it cannot change, can it? That's what const means.
No, it isn't.
const
means you can't change the thing. It doesn't mean it won't change. It doesn't mean it's a constant.
const
just gives you an immutable view of a thing. There may be other views of that thing, and those may be mutable.
does anything prevent an optimizing compiler from merging old_r and new_r into a single constant object
Yes: the fact that one of them would have the wrong value.
回答4:
Yes, the const values can change. When you do
const int& r = a;
you are creating a reference to a const int. The code that gets to use this variable will not be allowed to change the value via the reference. But it in no way suggests that the value stored there will not change.
See it as a variable with read-only permission. Some other piece of code might have write access.
You should compare with constexpr
which are truly constant expressions.
来源:https://stackoverflow.com/questions/54811374/a-const-refers-to-a-nonvolatile-variable-the-variable-changes-does-the-chang