AFAIK 从 const 变量中删除 constness 是未定义的行为:
const int i = 13;
const_cast<int&>(i) = 42; //UB
std::cout << i << std::endl; //out: 13
但是 const 函数参数是“真正的”常量吗?让我们考虑以下示例:
void foo(const int k){
const_cast<int&>(k) = 42; //UB?
std::cout << k << std::endl;
}
int main(){
foo(13); //out: 42
}
似乎编译器没有对 const int k
应用与 const int i
相同的优化。
第二个例子有UB吗? const int k
是帮助编译器优化代码,还是编译器只检查 const 的正确性,仅此而已?
最佳答案
const int i = 13;
中的 i
可以用作常量表达式(作为模板参数或 case 标签)并且尝试修改它是未定义的行为。这是为了向后兼容没有 constexpr
的 C++11 之前的代码。
声明 void foo(const int k);
和 void foo(int k);
声明相同的函数;参数的顶级 const
不参与函数的签名。参数 k
必须按值传递,因此不能是“真正的”常量。抛弃它的常量并不是未定义的行为。 编辑:但是任何修改它的尝试仍然是未定义的,因为它是 const object [basic.type.qualifier] (1.1):
A const object is an object of type const T or a non-mutable subobject of such an object.
通过[dcl.type.cv] 4 const object cannot be modified:
Except that any class member declared mutable (10.1.1) can be modified, any attempt to modify a const object during its lifetime (6.8) results in undefined behavior.
并且由于函数参数具有自动存储持续时间,因此无法通过 [basic.life] 10 也创建其存储中的新对象:
Creating a new object within the storage that a const complete object with static, thread, or automatic storage duration occupies, or within the storage that such a const object used to occupy before its lifetime ended, results in undefined behavior.
不清楚为什么 k
被声明为 const
如果有计划放弃它的常量?它的唯一目的感觉是混淆和混淆。
一般来说,我们应该在任何地方都支持不变性,因为它可以帮助人们进行推理。它还可以帮助编译器进行优化。然而,在我们只声明不变性但不尊重它的地方,它会起到相反的作用并造成混淆。
我们应该支持的另一件事是纯函数。这些不依赖于或修改任何外部状态并且没有副作用。这些也更容易为人们和编译器推理和优化。目前,此类函数可以声明为 constexpr
。然而,即使在 constexpr
函数的上下文中,将按值参数声明为 const
也无助于任何优化。
关于c++ - const 参数 "real"是常量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52754501/