【发布时间】:2017-04-27 01:49:06
【问题描述】:
在 c 中,可以使用如下指针更改 const:
//mainc.c
#include <stdio.h>
int main(int argc, char** argv) {
const int i = 5;
const int *cpi = &i;
printf(" 5:\n");
printf("%d\n", &i);
printf("%d\n", i);
printf("%d\n", cpi);
printf("%d\n", *cpi);
*((int*)cpi) = 8;
printf(" 8?:\n");
printf("%d\n", &i);
printf("%d\n", i);
printf("%d\n", cpi);
printf("%d\n", *cpi);
}
如果我们在 c++ 中尝试同样的方法:
//main.cpp
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char** argv) {
const int i = 5;
const int *cpi = &i;
cout << " 5:" << '\n';
cout << &i << '\n';
cout << i << '\n';
cout << cpi << '\n';
cout << *cpi << '\n';
*((int*)cpi) = 8;
cout << " 8?:" << '\n';
cout << &i << '\n';
cout << i << '\n';
cout << cpi << '\n';
cout << *cpi << '\n';
int* addr = (int*)0x28ff24;
cout << *addr << '\n';
}
从输出看,i 仍然是 5 并且仍然位于 0x28ff24,因此 const 没有改变。但同时cpi也是0x28ff24(与&i相同)但它指向的值是8(不是5)。
谁能解释一下这里发生了什么魔法?
【问题讨论】:
-
我想是未定义的行为。
-
虽然从语言的角度来看这是未定义的行为,但我们可以猜测 g++ 中发生了什么。我认为当您直接使用
i时,编译器会使用值 5。在您通过指针访问变量的地方,您将获得修改后的值。但是,在某些其他架构上,可以将常量放置在不可写内存中,并且尝试写入该内存可能会被硬件忽略或导致其他故障。 -
我发誓此常见问题解答存在规范副本,但我找不到。
-
顺便提一下,
printf("%d\n", &i);和printf("%d\n", cpi);都会调用未定义的行为,因为您使用了错误的格式说明符。