C++ const_cast问题

3
const int a = 1;
int *p = const_cast<int*>(&a);
*p = 2;
cout <<value a=<< a << endl;
cout <<value *p=<<*p << endl;
cout << “address a=<<&a << endl;
cout << “address p=<<p << endl;

输出:

value a=1
value *p=2
address a=0xbff1d48c
address p=0xbff1d48c

为什么相同的地址会有不同的值呢? 感到困惑。 谢谢!


我喜欢它以BFF开头的方式。 :) - user541686
在代码中捕捉到这个错误,可以使用pedantic-errors! - J T
2个回答

14

C++语言中修改常量对象是非法的,这样的尝试会导致未定义的行为。

在你的程序中,*p = 2 赋值尝试修改一个常量对象a,这个行为是未定义的。你观察到的奇怪输出正是这种未定义行为的结果。

对于未定义行为没有任何有意义的解释。

(你的编译器可能已经将 cout << a; 语句转换成了 cout << 1;,因为a的值不能合法地改变。所以无论你对a做了什么,都将始终打印出1.)


4
为了提供一个实际的原因:可能因为常量值是const,所以它被缓存到了某个地方,而另一个值则没有被缓存。因此你看到的是真实值和缓存的旧值。(这只是猜测)。 - crimson_penguin

2
除了AndreyT之外,您可能会想知道如果编辑常量会导致未定义的行为,那么为什么我们需要const_cast<>呢?const_cast<>旨在为出生时未受写保护的值获取写入权限。只需尝试以下更改即可得到正确的行为:
int b = 1;  // 'b' is modifiable
const int a = b;
...

不错的观点,尽管这不是唯一的观点(例如,const_cast<>也可以用于添加 const限定符)。 - Tony Delroy
1
@Tony:static_cast(因此甚至是隐式转换)可用于添加const限定符。const_cast专门设计用于删除const限定符。 - Serge Dundich
@Serge:是的,static_cast<>可以用来添加const,但如果const_cast<>只是设计用于删除它,那么它就不能添加它了;-P。我确实意识到有些人更喜欢使用static_cast<>-之前在SO上讨论过这个问题-我继续不同意他们的观点。如果您有一个逻辑上的理由更喜欢static_cast<>,而不仅仅是任意的断言,请分享一下。 - Tony Delroy
如果 const_cast<> 只是为了去除常量限定符而设计的,那么它就无法添加它。为什么呢?const_cast<> 提供了将 const/volatile 限定符更改为任何组合的能力,将其限制为仅删除限定符就不自然了。但是使用 const_cast 添加 const 是不安全的,因为您可能会意外地删除 volatile 限定符。此外,保留隐式转换而不是显式编写 const_cast 更加自然和简单。 - Serge Dundich
@Tony:那么 n = f(static_cast<const T>(x)); 怎么比你基于 const_cast 的表达式更差呢? 这个表达式拥有你的表达式的所有优点,但没有任何缺点。此外,编写者/读者绝对可以确定在每种情况下转换都是安全的(因为只有 static_cast 是如此安全的)。 - Serge Dundich
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接