Const值运行时求值

const values run-time evaluation

本文关键字:运行时 Const      更新时间:2023-10-16

以下代码的输出:

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

1(至少在VS2012下)

我的问题:

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

完全没有定义。你不能改变常量的值。

碰巧编译器把你的代码转换成类似

的东西
cout << 1 << endl;

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

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

这个行为定义了吗?

这段代码的行为没有被c++标准定义,因为它试图修改const对象。

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

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

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

在某些情况下,编译器确实会修改值并使用它,但它们并不可靠。

正如其他人所说,这种行为是未定义的。

为完整起见,以下是标准中的引语:

(§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

)

注意,这个词对象是指所有类型的对象,包括简单整数,如示例& & &;不仅仅是类对象。

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

答案是行为是未定义的。

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

#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

所以,就像你有相同的内存地址,但它保存了两个不同的值。

最可能的解释是编译器简单地将常量值替换为它们的文字值。

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

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

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

(在c++中使用类似C的操作符不是很好的做法)

可以,但必须将const初始化为只读const,而不是编译时const,如下所示:

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

c++的const关键字可以误导人,它要么是const,要么是只读的。