gcc - g++ 用于识别“const”变量修改的底层机制是什么?
问题描述
当我们声明一个变量为 const
const int cv = 3;
我猜 g++ 在数据区的某个地方(比如地址 0xFF77 )保留了 4 个字节。以后当人们访问 cv 时,编译器会去 0xFF77 获取值 3。
但是,编译器如何存储“const”信息?g++ 必须以某种方式存储此信息,因此当另一行尝试修改 cv 时,编译器知道“哦,这不正确,因为我知道 0xFF77 是 const”。
这里有人熟悉 gcc 编译器吗?你能给我一些见解吗?
谢谢
解决方案
一旦程序执行,编译器就不再存在。它的工作已经完成;该程序已被编译为可执行文件,然后可以在不安装编译器的情况下执行它。(因此,可以将可执行文件分发到没有编译器的机器上。)
但是,即使您的问题被重写以解决该问题,也存在一个毫无根据且不正确的假设:
g++ 必须以某种方式存储此信息,因此当另一行尝试修改
cv
时,运行时会知道“哦,这不正确,因为我知道 0xFF77 是 const”。
事实上,运行时没有义务阻止变量被修改。那是程序员的责任。当您将变量声明为 时const
,您是在通知编译器您不会修改其值,这可能使编译器能够更好地进行优化。如果事实证明您确实修改了变量,则此类优化可能会失败;const
修改声明的值是“未定义的行为”这一事实涵盖了这一点。(未定义的行为实际上是未定义的。抛出错误将是已定义的行为。)
在某些情况下,编译器实际上可以在编译期间检测到声明的变量const
正在被修改。
const int cv = 3;
cv = 42;
如果大多数编译器看到公然违反合同,他们会发出警告。但这是一个警告,而不是错误,而且有时编译器会被误导。例如,以下代码不会产生错误,假设函数always_false
名副其实:
const int cv = 3;
if (always_false(cv)) cv = 42;
简而言之,C++ 不承诺将您从错误中拯救出来;如果你选择用 C++ 编写程序,你必须做好准备,以确保你遵守规则。
推荐阅读
- csl - 多个作者分隔符
- postgresql - kubernetes timescaledb statefulset:在 pod 重新创建时丢失的更改
- spring-boot - Cucumber 测试在 Jenkins 中第一次构建失败,但是当多次运行构建时构建通过
- python - 无法点击不同的结果来解析内页的标题
- reactjs - onClick 使用 React 获取巡航列表标题
- eclipse - Eclipse Birt 中的日期和时间参数
- c# - 是否有任何 string.Contains 或相关方法
- php - 尝试创建表时无法修复 mysql 中的语法错误
- codeigniter - 登录页面中的挂钩给出错误 localhost 将您重定向了太多次
- php - Yii2 | 共享主机上的高级项目模板错误的重定向路线