【问题标题】:Casting a const int to a pointer? [duplicate]将 const int 转换为指针? [复制]
【发布时间】:2012-05-29 03:32:14
【问题描述】:

可能重复:
Modifying a const through a non-const pointer

我有以下代码:

const int x = 5;
int *p = (int*)&x;

*p = 2; // Line 1

cout << x << " - " << *p << endl;
cout << &x << " - " << p << endl;

并得到了结果:

5 - 2
0012FF28 - 0012FF28

我知道代码很奇怪,不应该这样做。但我想知道为什么相同的地址却得到不同的结果? Line 1 存储数字 2 的位置在哪里?

【问题讨论】:

  • 请您的编译器生成汇编列表并找出答案。可能会发生什么情况,您的编译器是否认为 xconst(正确如此),因此将值内联编译到您的第一个 cout 语句中。

标签: c++ pointers casting


【解决方案1】:

因为无论如何更改固有的const 变量的值是未定义的行为[Ref #1]

一旦你这样做了:

*p = 2; // Line 1

所有的赌注都被取消了,您的代码不再是有效的 C++ 代码,一旦编写了该行,您就不能期望任何特定的行为。推测为什么一个未定义的行为会给出任何特定的行为是没有意义的,因为它允许显示任何行为[Ref #2]这就是未定义的行为。


[Ref #1]
C++03 标准 7.1.5.1 cv 限定符:
第 4 段:

除了可以修改任何声明为 mutable (7.1.1) 的类成员外,任何在 const 对象的生命周期 (3.8) 期间修改它的尝试都会导致未定义的行为。

[参考 #2]
C++03 标准 1.3.24:

允许的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行期间以环境特征的记录方式表现(无论是否发出诊断消息),到终止翻译或执行(发出诊断消息)。

【讨论】:

  • 我阅读了您引用的文档中的部分,该文档提到了 cv-qualifiers。什么是 cv 限定符? (他们还说有 2 个 cv 限定符:const 和 volatile)
  • @ipkiss: cv(const-volatile)-qualifiers 是 (data)type 限定符,它们为 (data ) 类型对象。
【解决方案2】:

声明const 允许编译器假定该值不会改变。这意味着他们可以使用“立即”指令来加载值5,而不是引用分配给x 的位置(如果有的话)。

此外,修改 const 违反了您向编译器提供的保证,即该“变量”不会被修改,并且可能产生各种意外行为。

【讨论】:

    【解决方案3】:

    虽然一些编译器确实为 const 值分配了地址,但访问它是一个很大的禁忌。你得到 5-2 的原因是因为编译器直接用 5 替换 x,即使你修改了如果 x 不是 const 的地址,除非你通过 p* 访问 x 的值,否则你将要无论你做什么,每次都得到 5 - 而且, p* 可能会产生一个未定义的值,因为获取 const 的地址实际上可能会在某些编译器中失败(我认为所有编译器都应该这样做)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-10
      • 2013-10-20
      • 2017-02-12
      • 2012-03-02
      • 2014-05-02
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多