C ++ const指针 - 不明原因的行为

时间:2017-04-25 09:52:09

标签: c++ pointers reference

我有这段代码:

const int x = 7;
const int &y = x;

int *z = (int*)&y;
*z = 8;

cout << x<< endl;
cout << y<< endl;
cout << *z<< endl;

产生以下输出:

7
8
8

我知道不应该像上面那样删除const。但是,为什么x打印7?我只创建了一个var,所以如果输出显示7和8,那么应该创建2个vars。怎么会有两个不同的数字印刷。

3 个答案:

答案 0 :(得分:8)

  

我知道不应该像上面那样删除const。

右。这样做是未定义的行为,这意味着任何都可能发生。 (更准确地说,创建z不是未定义的行为;通过它修改x是。)

  

但是,为什么x打印7?我只创建了一个var,所以如果输出显示7和8,则应该创建2个vars。怎么会有两个不同的数字印刷。

关于未定义行为的推理很奇怪 - 但是理解调试目的是什么有用。在这种情况下,几乎可以肯定的是,编译器已经优化了:

cout << x<< endl;

cout << 7 << endl;

因为你无法合法地修改x的值。然后,您可以非法修改x的值,并设法打印出新值。

重要提示

不要试图依赖这种行为;正如我上面所说,它仅用于调试目的。如果编译器更改它可能会在优化时变得更好并且只为所有值打印7(因为*z = 8是未定义的行为),或者它可能将x放在只读内存中(并导致访问冲突) ,或者它可能最终为所有值打印8,或者可能发生任何其他事情。

答案 1 :(得分:3)

  

但是,为什么x打印7?

修改const对象具有未定义的行为。

答案 2 :(得分:2)

抛弃const并使用指针修改const对象具有未定义的行为。你看到了结果。

该标准甚至与您发布的示例几乎相同。

[dcl.type.cv/4]

  

除了声明可变的任何类成员都可以修改,任何   尝试在其生命周期内修改const对象   未定义的行为。 [实施例:

const int ci = 3;                       // cv-qualified (initialized as required)
ci = 4;                                 // ill-formed: attempt to modify const

int i = 2;                              // not cv-qualified
const int* cip;                         // pointer to const int
cip = &i;                               // OK: cv-qualified access path to unqualified
*cip = 4;                               // ill-formed: attempt to modify through ptr to const

int* ip;
ip = const_cast<int*>(cip);             // cast needed to convert const int* to int*
*ip = 4;                                // defined: *ip points to i, a non-const object

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
     

另一个例子,

struct X {
  mutable int i;
  int j;
};
struct Y {
  X x;
  Y();
};

const Y y;
y.x.i++;                                // well-formed: mutable member can be modified
y.x.j++;                                // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y);              // cast away const-ness of y
p->x.i = 99;                            // well-formed: mutable member can be modified
p->x.j = 99;                            // undefined: modifies a const member
     

- 结束示例]