c++ 当 const 不是显式的?

c++ when the const is not an explicit one?

我在 Internet 和 Whosebug 上搜索了关于 const_cast<> 及其引起的混乱,我找到了有用的东西,但是我仍然有一个问题。

考虑到这段代码,

#include <iostream>
using namespace std;

int main(void)
{
    const int a = 1;
    int *p = const_cast<int*>(&a);
    *p = 2;

    cout << "value a="<< a << endl;
    cout << "value *p=" <<*p << endl;
    cout << "address a=" <<&a << endl;
    cout << "address p=" <<p << endl;
}

输出为:

value a=1
value *p=2
address a=0x69fef8
address p=0x69fef8

我发现这样的代码可能会导致未定义的行为。 (例如,编译器可能会将所有 a 替换为 1 以进行优化,因此转换没有意义)

我还找到了这句话:

If you cast away the constness of an object that has been explicitly declared as const, and attempt to modify it, the results are undefined.

However, if you cast away the constness of an object that has not been explicitly declared as const, you can modify it safely.

还有这个:

Note that C++ provides const_cast to remove or add constness to a variable. But, while removing constness it should be used to remove constness off a reference/pointer to something that was not originally constant.

现在,考虑对上面的代码进行以下修改:

int b = 1;
const int a = b;

输出是:

value a=2
value *p=2
address a=0x69fef4
address p=0x69fef4

我明白了:

a in int a = 1 是编译时处理的常量表达式。
int a = b 中的 a 不是,只能在 运行 时处理。

如所述here

我的问题:

const 声明什么时候是显式的,什么时候不是?以及它最初怎么可能是非常量的?

有效的简单反例:

void foo(const int *a) {            // Pointer-to-const here
    int *p = const_cast<int*>(a);
    *p = 2;
}

int main() {
    int a = 1;                      // But underlying object is not const
    foo(&a);
}

在这个例子中:

int b = 1;
const int a = b;

a 是顶级 constb 不是。

如果您要将它们传递给这样的函数:

void f(const int &i){
    const_cast<int &>(i)++;
}

那么 f(a) 是非法的,因为您正在更改顶级 const 对象,该对象从一开始就被声明为 const,因此您的程序将显示未定义行为。
另一方面,f(b) 会很好,因为 b 开始时不是 const,然后通过参数转换将 const 添加到它,然后得到const 再次删除。由于 b 开始是可修改的,您可以通过删除添加的 const 来修改它。