const&指非易失性变量。变量改变。更改会使const&无效吗?

时间:2019-02-21 16:03:53

标签: c++ reference const undefined-behavior const-reference

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

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

  

const左值引用是指一个常量,从引用用户的角度来看,该常量是不变的。

那呢?

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

  • 地址&new_r既不在此行也不在代码中的其他地方提取,并且
  • 代码没有volatile

是否有什么办法阻止优化的编译器将old_rnew_r合并到单个常量对象中,从而将该行视为如下所示?

    const int& new_r = old_r;

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

相关问题

我发现的最接近相关的现有问题是:

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

另请参阅N4659(C ++ 17标准草案),第19节。 10.1.7.1,“ cv限定词。

问题顶部的Stroustrup语录来自教派。 C ++编程语言的第7.7.2版。当然,没有作者能在一千页的书中完美地写下每个句子。但也许Stroustrup很清楚,我只是看错了他。但是,您可能会明白为什么这句话使我感到困惑。这就是我问的原因。

4 个答案:

答案 0 :(得分:9)

  

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

是的,这完全合法。将=IF(AND(COUNTA(D8:F8)>0,NOT(ISBLANK(C8)),NOT(ISBLANK(G8))),IF(AND(C8=0.5,NOT(ISBLANK(D8))),100-(((D8-56)*5)+(G8*1)),IF(AND(C8=0.55,NOT(ISBLANK(E8))),100-(((E8-102)*5)+(G8*1)),IF(NOT(OR(C8=0.5,C8=0.55)),100-(((F8-108)*5)+(G8*1)),""))),"") 带入某个变量并不会阻止该变量被修改,这仅意味着您无法通过引用来修改该变量。那是

const&

将打印

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

我曾经尝试过

43 43

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

答案 1 :(得分:4)

  

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

不,不是。

const表示无法更改。这并不意味着它不会改变。这并不意味着它是一个常数。

const仅为您提供了事物的一成不变的观点。关于那件事可能还有其他观点,而这些观点可能是可变的。

  

任何事情都会阻止优化的编译器将old_r和new_r合并到单个常量对象中

是的:事实之一是错误的值。

答案 2 :(得分:4)

  

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

是的,但不是通过该引用(忽略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
  

是否有什么办法阻止优化的编译器将old_r和new_r合并到单个常量对象中,从而将该行视为如下所示?

as-if规则允许编译器优化可见副作用是否相同,
在这种情况下不是。因此,幸运的是,您的代码中“拟议的变量合并”无法完成。

答案 3 :(得分:2)

是的,const值可以更改。当你做

const int&    r = a;

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

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

您应该将constexpr与真正的常量表达式进行比较。