为什么字面值不是常量(除了字符串)?

9

字面量通常是prvalue

字符串是一种特殊情况,被定义为char数组(意味着lvalue)。

这个问题特别涉及到非字符串字面量。

为什么非字符串字面量不是const

foo(42); // passes foo an `int`, not a `const int`.

非字符串常量是无法被修改的,因此将其设为const是很有意义的,不是吗?


你有想到有哪些使用情境会有所影响吗? - Angew is no longer proud of SO
4
函数参数中的顶层const限定符无论如何都会被忽略(即void foo(const int)void foo(int)相同)。那么它会有什么区别呢? - Useless
4
不是重复问题 - 标题明确排除了字符串字面量,因此关于字符串字面量的问题实际上不可能是一个重复问题。 - MSalters
我真的想不出这会有什么区别,除了字面上写 decltype(42)。你能详细说明一下它会带来什么吗? - Angew is no longer proud of SO
1
历史的偶然性。在 C 语言中,你能否修改某个值完全取决于该值所属的值类别(lvalue 可修改,rvalue 不可修改),但要注意的是,修改字符串字面量(一个 lvalue)是未定义行为,这是类型系统的一个缺陷。因此,当 C++ 尝试修复这个问题时,它将 const 添加到字符串字面量的类型中,使它们在静态上不可修改。其他字面量一开始就是静态不可修改的,因此没有人觉得有必要将它们设为 const - n. m.
显示剩余2条评论
2个回答

6
字面意思是因为文字在语言中加入const之前就存在了,所以它们自然不是const。但实际上,const prvalues是根本奇怪的东西。您无法从任何基本类型创建它们,但可以有一个类类型的const prvalue。但是...为什么?通常,我们使事物成为const以防止进一步修改。但如果它是一个prvalue,它甚至不是具有标识的东西 - 谁会在那里观察到它的意外修改? const prvalues 防止移动 - 因为它们是const,所以您无法从它们移动,所以这是一种过早的恶化。请注意,唯一可能出错的事情,假设const字面量将防止发生的事情,已经被语言明确禁止了。
void foo(int&);
foo(42); // error

相比于将 42 定义为 const,该语言将左值引用定义为不允许绑定到右值。


3
请记住,C++默认情况下是按值传递的,这意味着值会被复制。由于只有在变量中拥有副本,因此无法修改数字文字值,例如42。字面值本身甚至不必存储在内存中,编译器可以直接在生成的代码中使用它。

没有办法修改数字字面值,那为什么不用 const 呢? - Ivan Rubinson
1
@IvanRubinson 因为你不能做 42 = 5 吗?既然数字字面量本质上已经是常量,所以没有必要将它们变成常量。一旦你将数字字面量存储在变量中,你就有了一个副本,这个副本可以随意修改,因为它不再是原始的字面值。 - Some programmer dude
“没有必要将数字字面量设置为常量,因为它们本质上已经是常量了。” - 这听起来有些可疑。如果它本质上是 const,那为什么不是 const 呢? - Ivan Rubinson
@IvanRubinson 看起来你没有在听。最后一次提醒,一旦你将数字字面值放入变量中,你所处理的是变量,而不是字面本身!数字字面值是一个prvalue,它们永远不会出现在赋值语句的左侧。你不能获取(指向)数字字面值的地址,在语言中也没有修改数字字面值的方法。 - Some programmer dude
字面量有类型。int 字面量的类型为 int。如果字面量不能被修改,为什么它的类型不是 const int(除了是 prvalue)? - Ivan Rubinson
1
@IvanRubinson - 因为成为一个纯右值已经足够了。它不是一个对象,只是一个(模糊的)值,可以用来创建一个对象。 - StoryTeller - Unslander Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接