首页 > 解决方案 > 在 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

标签: c++

解决方案


任何修改声明的变量或成员的程序const都不再具有 C++ 标准定义的行为。

这被称为 UB。UB 的常见症状是崩溃、“它似乎工作”、奇怪的不一致状态,甚至是未来 UB在代码中发生之前改变行为的时间旅行。

一个优秀的 C++ 程序员会养成使 UB 不太可能发生的习惯。

您在这里看到的 UB 的症状是,由于 C++ 标准规定的行为没有任何程序const int x=5;可以具有除 之外的任何值5,因此编译器将 reads 替换为x常量5

另一方面,您可以形成一个指向 的指针x,并且x那里确实有字节。编译器可以自由地放入xROM 或受保护的页面,或者它可以不打扰并将其放入普通内存中。

你形成一个指向x. 编译器不会忽略此指针(允许但也不允许),因此在您的机器代码中,它实际上会读取和写入存储地址处x的数据。因此,如果编译器优化指针,*&x则为10while x is5 . What more, *&x could be5`。

避免UB。

C++ 定义了一个抽象机器,并且 C++ 程序在其上定义了行为(除非您使用 UB)。然后将其转换为保证与抽象机器行为一致的机器代码,但根本不能保证天真地看起来“应该”映射到某些机器代码的 C++ 代码。

抽象和具体之间的差距允许进行大量优化。

C++ 抽象机器行为旨在轻松映射到机器代码,而 UB 留在执行某些行为会产生成本的地方。


推荐阅读