Const变量随C中的指针而更改
Const variable changed with pointer in C
变量i
被声明为const,但我仍然可以用指向其内存位置的指针来更改值。这怎么可能?
int main()
{
const int i = 11;
int *ip = &i;
*ip=100;
printf("%dn",*ip);
printf("%dn",i);
}
当我编译时,我会收到以下警告:
test.c: In function ‘main’:
test.c:11: warning: initialization discards qualifiers from pointer target type
输出是这个
100
100
const
不是向编译器发出的使其无法更改该变量的请求。相反,这是对编译器的一个承诺,而您不会这样做。如果你违背了你的承诺,你的程序可以做任何事情,包括崩溃。
例如,如果我使用-O2
优化级别的gcc编译您的示例代码,则输出为:
100
11
编译器允许将const
限定变量放置在只读内存中,但它没有到(除其他外,有些环境不实现任何此类功能)。特别是,将自动("本地")变量放在只读存储器中几乎总是不切实际的。
如果您将i
的声明更改为:
static const int i = 11;
那么您很可能会发现该程序现在在运行时崩溃。
const
是编译时功能
这并不能阻止你朝自己的脚开枪;这就是警告的意义所在。
虽然这在C中可能是一个警告,但在C++中这是一个编译器错误。
如果您设法在C/C++中强制转换这个const int
,那么它可能会导致未定义的行为。原因是,您正在将数字文本(即const int i =
11;
)从const
强制转换为可变值。
您的代码显示的内容和以下顺序之间存在差异:
int x = 11; // x is modifiable
const int i = x;
int *ip = (int*)(&i); // ok
*ip=100;
不能修改符合const
条件的对象。如果进行了这样的尝试,则程序显示出未定义的行为(C99 6.7.3.5)。(您的程序不正确。)
关于const
的更多信息:而非声明为const
的对象可以修改,但不能使用const
限定的lvalues。当涉及指针时,这一点最为明显。例如,考虑声明:
int i = 10;
int *p1 = &i;
const int *p2 = &i;
可以通过i
本身和通过p1
修改i
,但不能通过p2
修改。这意味着,即使p2
指向const
对象,*p2
也可以评估为不同的值,因为其他语句可能会更改p2
指向的对象(如示例中的混叠指针)。
但是,如果i
本身是const
限定的,那么尝试通过p1
修改它将产生未定义的行为(就像您的代码一样)。
不是试图修改i
导致程序行为未定义,而是ip
的初始化。
const int i = 11;
int *ip = &i;
CCD_ 28属于CCD_。CCD_ 30属于CCD_。试图用const int*
值初始化int*
是违反约束的行为。发布诊断需要符合要求的实施;一旦完成,它可能会也可能不会拒绝翻译单元。如果它接受它,C标准就不会对生成的程序的行为做任何说明。
接受这些东西的编译器通常会生成等效于从const int*
到int*
的转换的代码,从而使声明实际上等效于:
int *ip = (int*)&i;
但是语言不需要这种行为。
不要忽视警告
(请注意,使用强制转换,代码不会违反约束;然后是以下的行为
*ip = 100;
未定义,因为它试图修改const
限定的对象。)
特别是gcc在很多情况下,对违反约束的诊断(默认情况下)被处理为警告,而不是致命错误。我个人不喜欢gcc;它让太多坏代码通过。
(您的程序的行为也是未定义的,因为您在没有可见声明的情况下调用printf
;添加#include <stdio.h>
。并且int main()
应该是int main(void)
。)
- 指针变量在 cout 函数中不起作用
- 如何将指针变量作为引用参数传递?
- 有没有办法在同名类 (c++) 中为对象分配一个指针变量
- 我试图了解在异或操作后指针变量正在更改
- 调用带有指针对象错误的指针变量
- 如何在 cuda 中将结构的指针变量从主机复制到设备
- 非指针变量和类成员上的新放置
- 线路抑制状态错误 C4703 可能未初始化的局部指针变量"back"已使用
- 全局外部指针变量在 DLL 中不可见
- 如何访问在 c++ 中在类内声明的结构类型指针变量?
- C++ 中指针变量的内存释放
- 使用指针变量打印特定的数组变量
- 如何使用构造函数初始化内存地址(指针变量)?
- 如何释放为指针变量本身提供的内存?
- 如果地址已知,如何获取指针变量的名称
- 如何处理参数中的基类和指针变量
- 指针变量 在数组中定位零
- 隐式指针变量,在自动定义中具有另一个指针变量
- 为什么可以将Char指针变量初始化为字符串,而INT指针变量不能初始化到整数数组
- 错误 C4703 可能未初始化的局部指针变量'y'使用