更改 C++ 中 const 变量的值
我正在尝试更改定义为 int const 的变量的值,如下所示。
const int w = 10;
int* wp = const_cast <int*> (&w);
*wp = 20;
即使在赋值之后,w 的值也没有改变,仍然是 10,尽管它显示 w 和 wp 似乎都指向相同的内存位置。但是我可以更改 w 的值,如果定义如下,同时声明
int i = 10;
const int w = i;
如果我更改 i 的声明以使其成为 const,就像
const int i = 10;
w 的值不会改变一样。
在第一种情况下,为什么 w 的值没有改变,即使 w 和 wp 指向相同的内存位置[这是我打印它们的地址时得到的印象]
编译器对待两者有什么区别情况不同吗?
有没有办法确保 w 不会失去常量,无论它的定义方式如何?
I am trying to change the value of a variable which is defined as int const as below.
const int w = 10;
int* wp = const_cast <int*> (&w);
*wp = 20;
The value of w didn't change and was 10 even after the assignment, though it shows as if both w and wp are pointing to the same memory location. But I am able to the change the value of w, if defined as below while declaring
int i = 10;
const int w = i;
If I change the declaration of i to make it const like in
const int i = 10;
The value of w doesn't change.
In the first case, how come the value of w didn't change, even though w and wp point to the same memory location [ that was my impression I get when I print their addresses ]
What difference it's to the compiler that it treats both the cases differently?
Is there a way to make sure that w doesn't lose constness, irrespective of the way it is defined?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这是 const 强制转换未定义的情况之一,因为代码可能经过优化,使得 w 并不是真正的变量,并且在编译的代码中并不真正存在。
尝试以下操作:
无论如何,我不建议像这样滥用 const_cast 。
This is one of the cases where a const cast is undefined, since the code was probably optimized such that w isn't really a variable and does not really exist in the compiled code.
Try the following:
Anyhow, I would not advise abusing const_cast like that.
上面示例中的代码翻译成以下汇编程序:
由于原始 int i 被声明为常量,因此编译器保留使用文字值而不是存储在堆栈中的值的权利。这意味着该值不会改变,并且您将停留在原始的 10 上。
这个故事的寓意是编译时常量应该保持不变,因为这就是您告诉编译器的内容。这个故事的寓意是,为了改变常量而抛弃常量可能会导致糟糕的事情。
The code in the above example translates into the following assembler:
Because the original int i was declared constant, the compiler reserves the right to use the literal value instead of the value stored on the stack. This means that the value does not get changed and you are stuck with the original 10.
The moral of the story is compile time constants should remain constant because that is what you are telling the compiler. The moral of the story is that casting away constness in order to change a constant can lead to bad things.
const_cast
不会消除定义的变量的常量性。如果您要通过引用将非常量变量传递给采用 const 引用的方法,例如 void foo(const int& x) ,那么您可以使用 const_cast 来修改foo
中x
的值,但前提是您实际传入的变量一开始就不是 const。const_cast
doesn't take away the const-ness of a variable as defined. If you were to pass a non-const variable by reference in to a method taking a const reference likevoid foo(const int& x)
then you could useconst_cast
to modify the value ofx
withinfoo
, but only if the variable you actually passed in was not const in the first place.为什么不能重新绑定常量呢?因此,不要仅仅
引入同名的不同常量
如果“新”常量应该依赖于它自己的值,您应该引入另一个常量 (
const int _w = w; const int w = _w * 2;
const int _w = w; const int w = _w * 2;)。不必要的分配将被编译器优化——因为我们已经看到它已经做了这样的优化,因为这就是你问问题的原因。Why can't you just re-bind the constant? So instead of
just introduce the different constant with the same name
If the "new" constant should depend on its own value, you should introduce another constant (
const int _w = w; const int w = _w * 2;
). The unnecessary assignments will be optimized out by compiler--because we've seen it has done such optimisation, as it's the reason why you asked your question.您不应该更改 const 值。它是 const 是有原因的,尝试更改它很可能只会导致错误。如果常量存储在只读内存部分中,那么您将遇到访问冲突。
You should not being changing the const value. There is a reason it is const and trying to change it will most likely just result in errors. If the const is stored in a read only memory section then you will get access violations.
好问题。我认为这种混乱来自于 C++ 根据上下文使用关键字“const”来表示两个不同的概念。这些概念是常量和只读变量。
当可以在编译期间计算“const”变量的值时,它会创建一个真正的常量。每当使用该常量时,对该常量的引用都会被其值替换。这就是为什么内存中没有可以更改的位置来影响所有使用它的地方。就像使用#define 一样。
当编译期间无法计算“const”变量的值时,它会创建一个只读变量。它在内存中有一个位置包含一个值,但编译器强制执行只读行为。
Good question. I think the confusion comes from the fact that C++ uses the keyword ‘const’ for two different concepts depending on the context. These concepts are constant and read-only variables.
When a value of a ‘const’ variable can be calculated during the compilation, it creates a true constant. References to such constant are replaced with its value whenever it is used. That’s why there is no location in the memory that can be changed to affect all places where it is used. It is like using #define.
When value of a ‘const’ variable cannot be calculated during the compilation, it creates a read-only variable. It has a location in the memory that contains a value but compiler enforces a read-only behavior.
这是一个复习,应该注意的是这是用 C 语言编写的。这是使用
const
关键字使用变量或指针的一个看似棘手的基础。这突出了指针变量 foo 之间的区别以及如何通过使用所述关键字来改变它的含义。第一个和最后一个声明使“foo”指向的数据为只读,但是,您可以更改“foo”指向的地址,例如
上面的中间声明,使 < em>指针只读,即不能更改“foo”指向的数据的地址
Here's a refresher, it should be noted that this is in C. This is a deceptively tricky underpinnings of the usage of a variable or pointer using the
const
keyword. This highlights the difference between the pointer variablefoo
and how the meaning of it can change by using the said keyword.The first and last declarations, makes the data pointed to by ‘foo’ read-only, but, you can change the address pointed to by ‘foo’ e.g.
The middle declaration in the above, makes the pointer read-only, i.e. you cannot change the address of the data pointed to by ‘foo’
我的猜测是,声明 w const 允许编译器执行更积极的优化,例如内联 w 的值和重新排序指令。 w 是否会发生变化取决于在具体情况下应用了哪些优化,并且不受您的控制。
你不能强迫 w 是完全 const 的。 cons_cast 应该向程序员暗示他们可能正在做一些可疑的事情。
My guess would be that declaring w const allows the compiler to perform more aggressive optimizations such as inlining w's value and reordering instructions. Wether w appears to change or not depends on which optimizations were applied in the precise case and is not under your control.
You can't force w to be totally const. The cons_cast should be a hint to the programmer that they might be doing something fishy.