为什么通过指针赋值常量没有效果?



在下面的示例中,"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;

是错误的。 该标准将这种类型的行为(通过与赋值目标类型不匹配的指针进行赋值(称为"未定义行为",这意味着编译器不需要生成警告消息(如果这样做会很好(,但这也意味着编译器不需要生成以预期方式实现语句的代码。

您可以在此处阅读有关未定义行为和相关语言问题的更多信息

最新更新