#include <stdio.h>
int main(void) {
const int a = 4;
int *p = (int*)&a;
printf("%d\n", a);
*p = 6;
printf("%d\n", a);
return 0;
}
代码在C和C ++编译器上提供了不同的输出:
//In C:
4
6
//In C++:
4
4
答案 0 :(得分:5)
尝试修改const
值(只读值)是未定义的行为。输出可以是任何东西,或程序可能崩溃,或推动你的狗进入太空。你已被警告过了。
关于const
,常量和只读值
const
是一个选择不当的关键字,因为它并不代表&#34;常数&#34;,而是&#34;只读&#34;。 &#34;常量&#34;是给予只读值的名称,没有别的。与'#34;只读&#34;相反(这里)是&#34;读写&#34;,&#34;常数&#34;是可变的&#34;。 Mutable是C和C ++中的默认值(除了一些罕见的极端情况,如lambdas)。考虑一下:
int i = 4; // (mutable) Value
int const j = 4; // Read-only value, a.k.a constant
// Pointer to a (mutable) value. You can write to the value through it.
int *pi = &i;
// Pointer giving read-only access to a value. The value
// is still mutable, but you can't modify it through cpi.
int const *cpi = &i;
// Since the value is mutable, you can do that and write to *p2i
// without trouble (it's still bad style).
int *p2i = (int*)cpi;
// Pointer giving read-only access to a value.
// The value is a constant, but you don't care
// since you can't modify it through cpj anyway.
int const *cpj = &j;
// This is legal so far, but modify *pj
// (i.e the constant j) and you're in trouble.
int *pj = (int*)cpj;
你什么时候可以这样做?
允许转换const
的唯一情况是将指针(或引用)传递给您无法修改的错误声明的函数(或类似函数):
// Takes a non-const pointer by error,
// but never modifies the pointee for sure
int doSomething(Foo *foo);
// Your function, declared the right way
// as not modifying the pointee
int callDoSomething(Foo const *foo) {
// Work around the declaration error.
// If doSomething ever actually modifies its parameter,
// that's undefined behaviour for you.
int bar = doSomething((Foo*)foo);
}
你有什么不被咬的?
答案 1 :(得分:4)
它在C和C ++中都是未定义的行为。
不应修改const
变量,这包括直接修改它,它还包括间接修改它(通过示例中的指针)。
答案 2 :(得分:1)
虽然其他答案已经涵盖了它是未定义的行为,但这个演员在这里:
int* p = (int*)&a;
很糟糕。它隐藏了你应该得到的警告:
main.cpp:6:10: warning: initialization discards 'const' qualifier from pointer target type
int* p = &a;