A const & refers to a nonvolatile variable. The variable changes. Does the change invalidate the const &?

佐手、 提交于 2019-12-13 00:39:18

问题


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

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