const值运行时评估

时间:2012-12-26 13:04:55

标签: c++

以下代码的输出:

const int i= 1;
(int&)i= 2;          // or:  const_cast< int&>(i)= 2;
cout << i << endl;

1 (至少在VS2012下)

我的问题:

  • 是否定义了此行为?
  • 编译器是否总是使用定义的常量值?
  • 是否可以构建编译器将使用最新赋值的值的示例?

6 个答案:

答案 0 :(得分:7)

完全未定义。你无法改变常量的值。

编译器恰好将代码转换为类似

的代码
cout << 1 << endl;

但程序也可能崩溃,或做其他事情。

如果您将警告级别设置得足够高,编译器肯定会告诉您它不会起作用。

答案 1 :(得分:4)

  

是否定义了此行为?

此代码的行为未由C ++标准定义,因为它尝试修改const对象。

  

编译器是否总是使用定义的常量值?

编译器在这种情况下使用的值取决于实现。 C ++标准没有强制要求。

  

是否可以构造一个编译器将使用最新赋值的示例?

可能存在编译器修改值并使用它的情况,但它们不可靠。

答案 2 :(得分:3)

答案是行为未定义。

我设法建立了这个结论性的例子:

#include <iostream>

using namespace std;

int main(){

        const int i = 1;

        int *p=const_cast<int *>(&i);
        *p = 2;
        cout << i << endl;

        cout << *p << endl;

        cout << &i << endl;

        cout << p << endl;

        return 0;
}

,在gcc 4.7.2下给出:

1
2
0x7fffa9b7ddf4
0x7fffa9b7ddf4

因此,就像你拥有相同的内存地址,因为它拥有两个不同的值。

最可能的解释是编译器只是用它们的文字值替换常量值。

答案 3 :(得分:3)

正如其他人所说,行为未定义。

为了完整起见,以下是标准的引用:

  

(§7.1.6.1/ 4)除了可以修改任何声明为可变的类成员(7.1.1)之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。 [例如:

     

[...]

const int* ciq = new const int (3);  // initialized as required
int* iq = const_cast<int*>(ciq);     // cast required
*iq = 4;                             // undefined: modifies a const object
     

注意, object 这个词是指这个段落引用的各种对象,包括简单的整数,如例子所示 - 不仅仅是类对象。

虽然该示例引用了指向具有动态存储的对象的指针,但该段落的文本清楚地表明这也适用于对具有自动存储的对象的引用。

答案 4 :(得分:-1)

您正在使用类似C的const_cast进行cast operator

使用const_cast并不能保证任何行为。

如果您这样做,它可能会起作用,也可能不起作用。

(在C ++中使用类似C的运算符并不是一种好习惯)

答案 5 :(得分:-2)

是的,你可以,但只有当你将const作为只读而不是编译时const时,如下所示:

int y=1;
const int i= y;
(int&)i= 2;
cout << i << endl; // prints 2

C ++ const关键字可以是missleading,它可以是const或只读。

相关问题