在下面的示例中,"ptr"指向常量变量"local"。为什么通过分配"*ptr"来修改"local"不会改变"local"的值?
#include <stdio.h>
int main(void)
{
const int local = 10;
int *ptr = (int*) &local;
printf("address of local: %p n", &local);
printf("value of ptr: %p n", ptr);
printf("Initial value of local : %d n", local);
printf("Initial value of *ptr : %d n", *ptr);
*ptr = 100;
//*((int*)&local) = 1000;
printf("Modified value of local: %d n", local);
printf("Modified value of *ptr: %d n", *ptr);
printf("address of local: %p n", &local);
printf("value of ptr: %p n", &(*ptr));
return 0;
}
输出:
address of local: 0x7ffd946bd9c4
value of ptr: 0x7ffd946bd9c4
Initial value of local : 10
Initial value of *ptr : 10
Modified value of local: 10
Modified value of *ptr: 100
address of local: 0x7ffd946bd9c4
value of ptr: 0x7ffd946bd9c4
行:
*ptr = 100;
是未定义的行为。原因是ptr
指向一个const
对象。你通过丢弃常量来编译这个,但语言仍然说实际修改声明 const 的对象是非法的:http://en.cppreference.com/w/cpp/language/const_cast。
未定义行为的存在基本上意味着您的程序可以在不同的编译器/优化级别上做许多不同的奇怪事情。简而言之,不要修改const
对象,现在要避开const_cast
。这通常是设计不佳的标志;它的合法用途相对较少,您将边走边学。以下是罕见的有效const_cast
使用示例的链接:如何删除类似的 const 和非 const 成员函数之间的代码重复?这种技术消除了代码重复,但从根本上说,当只有指针是常量限定的,但已知底层对象不是常量时,它依赖于丢弃常量。
实际const
值与const
锯齿指针/引用之间的差异在C++中非常重要。
此语句:
int *ptr = (int*) &local;
其次
*ptr = 100;
是错误的。 该标准将这种类型的行为(通过与赋值目标类型不匹配的指针进行赋值(称为"未定义行为",这意味着编译器不需要生成警告消息(如果这样做会很好(,但这也意味着编译器不需要生成以预期方式实现语句的代码。
您可以在此处阅读有关未定义行为和相关语言问题的更多信息