1

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:

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.

4

4 回答 4

9

在 C++ 中,const & 的值可以改变吗?

是的,这是完全合法的。使用const&某个变量并不能阻止该变量被修改,它只是意味着您不能通过引用修改该变量。这意味着

int a = 42;
int const& b = a;
++a;
std::cout << a << " " << b;

将打印

43 43

如果我试着做

++b;

尽管这将是一个编译器错误,因为b对值的访问是const并且++是非常量操作。

于 2019-02-21T16:06:37.643 回答
4

好吧,它当然不能改变,不是吗?这就是 const 的意思。

不,不是。

const意味着不能改变这件事。这并不意味着它不会改变。这并不意味着它是一个常数。

const只是给你一个不可变的事物视图。对那件事可能有其他观点,而且这些观点可能是可变的。

是否会阻止优化编译器将 old_r 和 new_r 合并到单个常量对象中

是的:其中之一的价值是错误的。

于 2019-02-21T16:10:07.700 回答
4

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.

于 2019-02-21T16:12:36.467 回答
2

是的,常量值可以改变。当你这样做

const int&    r = a;

您正在创建对 const int 的引用。使用此变量的代码将不允许通过引用更改值。但这绝不意味着存储在那里的值不会改变。

将其视为具有只读权限的变量。其他一些代码可能具有写访问权限。

您应该比较constexpr哪些是真正的常量表达式。

于 2019-02-21T16:08:42.323 回答