gra*_*tot 16 c c++ pointers const
在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);
}
Run Code Online (Sandbox Code Playgroud)
如果我们在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';
}
Run Code Online (Sandbox Code Playgroud)
从输出看起来i
仍然5
是仍然位于0x28ff24
所以const不变.但同时cpi
也是0x28ff24
(相同&i
),但它指出的价值是8
(不是5
).
有人可以解释一下这里发生了什么样的魔法?
Bat*_*eba 34
抛弃const
最初声明为变量(甚至通过C++中的指针或引用),const
然后尝试通过该指针或引用更改变量的行为是未定义的.
因此,i
如果它被声明为更改const int i = 5;
是未定义的行为:您正在观察的输出是其表现形式.
Lun*_*din 15
根据C11 6.7.3/6,它是未定义的行为:
如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为是未定义的.
(C++将有类似的规范性文本.)
由于它是未定义的行为,任何事情都可能发生.包括:奇怪的输出,程序崩溃,"似乎工作正常"(这个版本).