Const值运行时求值
const values run-time evaluation
以下代码的输出:
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,要么是只读的。
相关文章:
- CMake-按正确顺序将项目与C运行时对象文件链接
- 我在c++代码中生成了一个运行时#3异常
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在运行时更改const wchar_t*
- 是否有一种方法可以在运行时识别变量的const修饰符
- 运行时初始化 a const
- 使用 const char 数组参数分析 constexpr 显示运行时执行
- 使用帮助程序函数 (c++) 定义运行时已知的全局 const 变量
- 将QString转换为const-char*时的不可预测的运行时行为
- 定义需要在运行时设置的const静态
- 为什么在这个代码示例中发生与返回const引用相关的运行时错误
- 在运行时使用 'const' 参数构造类
- 在运行时赋值const
- Const值运行时求值