为啥通过指针分配给常量没有效果? [复制]
Posted
技术标签:
【中文标题】为啥通过指针分配给常量没有效果? [复制]【英文标题】:Why does assigning to a constant via pointer have no effect? [duplicate]为什么通过指针分配给常量没有效果? [复制] 【发布时间】:2017-08-22 16:18:35 【问题描述】:在下面的示例中,“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
【问题讨论】:
因为丢弃***const
对象的const
是未定义的行为。
@nwp 实际上,这并不完全正确,演员表本身不是 UB。实际修改的只有UB。一般来说,C++ 中的指针强制转换很少会直接导致 UB(我确信有例外)。它通常是 UB 的错误转换指针的 用法。
如果你说某个东西是 const,它取决于编译器如何处理它。据你所知,它被放在只读存储器的某个地方,因为你说过你不会改变它。现在你正在尝试编辑它。你为什么希望它改变?
const 在很多情况下根本就没有地址(直接值 10 用于机器码)
谢谢大家:)。现在我明白了。
【参考方案1】:
行:
*ptr = 100;
是未定义的行为。原因是因为ptr
指向一个const
对象。您通过抛弃 const 来进行编译,但该语言仍然说实际修改声明为 const 的对象是非法的:http://en.cppreference.com/w/cpp/language/const_cast。
未定义行为的存在基本上意味着您的程序可以在不同的编译器/优化级别上执行许多不同的、奇怪的事情。简而言之,不要修改const
对象,暂时避开const_cast
。这通常是糟糕设计的标志;它的合法用途相对较少,您将在学习过程中学习。下面是一个罕见的有效使用 const_cast
示例的链接:How do I remove code duplication between similar const and non-const member functions?。这种技术消除了代码重复,但从根本上说,它依赖于在只有 指针 是 const 限定的情况下丢弃 const-ness,但已知底层对象不是 const。
实际const
值与const
别名指针/引用之间的区别在C++ 中非常重要。
【讨论】:
谢谢,尼尔弗里德曼。我会接受你的回答。 @HeChen - 这是明智的:p【参考方案2】:此声明:
int *ptr = (int*) &local;
紧随其后
*ptr = 100;
错了。标准将这种类型的行为(通过与赋值目标类型不匹配的指针赋值)称为“未定义行为”,这意味着编译器不需要产生警告消息(如果它会很好确实),但这也意味着编译器不需要生成按照您期望的方式实现语句的代码。
您可以阅读有关未定义行为和相关语言问题的更多信息here
【讨论】:
不,这个答案是错误的,演员表本身不是UB。只有作业是。 抛弃 const 不是 UB,有时必须使用一些遗留的 C 接口来完成。在你抛弃 const 之后修改值是。 你是对的,当然。我试图简化。以上是关于为啥通过指针分配给常量没有效果? [复制]的主要内容,如果未能解决你的问题,请参考以下文章