const & 指的是非易失性变量。变量发生变化。更改是否会使 const & 无效?

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

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

嗯,当然不能改变,可以吗?这就是 const 的意思。此外,听听 Stroustrup:

A const lvalue reference refers to a constant, which is immutable from the point of view of the user of the reference.

但是这个呢?

#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;
}

在我的机器上,输出 old_r == 0 but new_r == 1

这就是我真正的问题。在上面的代码中,查看行

    const int new_r = r;

只要

是否有任何事情阻止优化编译器将 old_rnew_r 合并到一个常量对象中,并将该行视为如下所示?

    const int& new_r = old_r;

我问是因为据我所知,如果编译器进行了优化,那可能会改变行为。该程序可能会输出,old_r == 0 but new_r == 0.

相关问题

我发现最相关的现有问题是这个:

以下也是相关的,但与当前问题不同的是,涉及强制转换:

另见 N4659(C++17 标准草案),节。 10.1.7.1,"The cv-qualifiers."

问题顶部 Stroustrup 的引述来自教派。 C++ 编程语言的 7.7.2, 第 4 版。当然,没有作者能在一千页的书中把每一句话都写得完美无缺;然而也许 Stroustrup 是清楚的,我只是误读了他。不过,您可能会明白为什么这句话让我感到困惑。这就是我问的原因。

In C++, can the value of a const & change?

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

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

将打印

43 43

我试过吗

++b;

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

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

const int&    r = a;

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

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

你应该与 constexpr 进行比较,后者是真正的常量表达式。

Well, of course it cannot change, can it? That's what const means.

不,不是。

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

const 只是让您对事物有一个不变的看法。对那件事可能还有其他看法,而且这些看法可能是可变的。

does anything prevent an optimizing compiler from merging old_r and new_r into a single constant object

是的:事实上其中之一的值是错误的。

In C++, can the value of a const & change?

是的,但不是通过该引用(忽略 mutable 字段)。

void foo(const int& c, int& mut) {
    std::cout << c << " ";
    ++mut; // changes `c` if &c == &mut
    std::cout << c << std::endl;
}

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?

as-if 规则允许编译器在可见的副作用相同时进行优化,
不是这里的情况。所以你代码中的"proposed merge of variable"幸好无法完成。