c++ - 在 cpp 中创建一个变量 const 然后将其地址提供给一个指针,但取消引用不会改变变量,为什么?
问题描述
在 cpp 中创建一个变量 const 然后将其地址提供给一个指针并通过取消引用来更改其值,但我仍然获得了最初存储的值。
代码片段
const int a = 5;
// then
// a = 7; not possible
// bypassing const using pointers
int *ap = (int *)&a;
*ap = 10;
cout << *ap <<" "<< *(&a)<<" " << a << endl;
输出是:
10 10 5
解决方案
任何修改声明的变量或成员的程序const
都不再具有 C++ 标准定义的行为。
这被称为 UB。UB 的常见症状是崩溃、“它似乎工作”、奇怪的不一致状态,甚至是未来 UB在代码中发生之前改变行为的时间旅行。
一个优秀的 C++ 程序员会养成使 UB 不太可能发生的习惯。
您在这里看到的 UB 的症状是,由于 C++ 标准规定的行为没有任何程序const int x=5;
可以具有除 之外的任何值5
,因此编译器将 reads 替换为x
常量5
。
另一方面,您可以形成一个指向 的指针x
,并且x
那里确实有字节。编译器可以自由地放入x
ROM 或受保护的页面,或者它可以不打扰并将其放入普通内存中。
你形成一个指向x
. 编译器不会忽略此指针(允许但也不允许),因此在您的机器代码中,它实际上会读取和写入存储地址处x
的数据。因此,如果编译器优化指针,*&x
则为10
while x is
5 . What more,
*&x could be
5`。
避免UB。
C++ 定义了一个抽象机器,并且 C++ 程序在其上定义了行为(除非您使用 UB)。然后将其转换为保证与抽象机器行为一致的机器代码,但根本不能保证天真地看起来“应该”映射到某些机器代码的 C++ 代码。
抽象和具体之间的差距允许进行大量优化。
C++ 抽象机器行为旨在轻松映射到机器代码,而 UB 留在执行某些行为会产生成本的地方。
推荐阅读
- ruby-on-rails - 使用 xml 和 html 格式发布测试报告 rails
- python - 在 Python 中使用日期时间时出现此错误的原因可能是什么?
- azure-functions - Azure Functions 在运行时每 30 分钟更新一次密钥
- node.js - TypeError:_lodash2.default.get 不是函数
- java - Java更好地利用继承和抽象类
- r - 向 df 添加列:`$<-.data.frame 中的错误:替换有 x 行,数据有 153
- python-3.x - 我将如何编写一个函数来搜索文本文件,返回这些详细信息然后从文件中删除它们?
- html - 画布(甚至 svg)上的 CSS 最小高度有限制吗?
- ruby - Ruby块`block in Method':未定义的方法`inject'为true:TrueClass(NoMethodError)
- swagger-2.0 - Swagger 2.0 - 带有订单列表的有效负载