为啥文字不是 const (字符串除外)?

Posted

技术标签:

【中文标题】为啥文字不是 const (字符串除外)?【英文标题】:Why are literals not const (except strings)?为什么文字不是 const (字符串除外)? 【发布时间】:2018-08-29 12:16:22 【问题描述】:

文字通常是prvalues。 字符串是一种特殊情况,定义为char(意思是lvalue)的数组。 这个问题专门针对 not string 文字。

为什么非字符串文字不是const

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

您不能修改非字符串文字,所以将其设为 const 是否有意义?

【问题讨论】:

您是否想到了一个重要的用例? 函数参数上的*** const 限定符无论如何都会被丢弃(即void foo(const int)void foo(int) 相同)。那么它会有什么不同呢? 不是重复的 - 标题明确排除了字符串文字,所以关于字符串文字的问题字面上不能重复。 真的想不出有什么办法让这个有所作为,除了字面上写decltype(42)。你能详细说明它会带来什么吗? 历史事故。在 C 中,您可以修改和不能修改的内容完全取决于所讨论事物的值类别(左值是可修改的,右值不是),但需要注意的是修改字符串文字(左值)是 UB,它是一个类型系统疣。因此,当 C++ 尝试解决此问题时,它会将 const 添加到字符串文字的类型中,以使其静态不可修改。其他文字一开始是静态不可修改的,因此没有人认为有必要将它们设为const 【参考方案1】:

字面的答案可能是因为文字早于const 添加到语言中,所以它们自然不是const

但实际的答案是 - const prvalues 从根本上说是奇怪的东西。您不能从任何基本类型创建它们,但您可以拥有类类型的const prvalue。但为什么?通常,我们制作const 以防止进一步修改正确。但如果它是一个prvalue,它甚至不是一个有身份的东西——谁会在那里观察它的意外修改? const prvalues 阻止移动 - 因为它们是 const,所以你不能离开它们,所以它是过早的悲观。

请注意,可能出错的一件事,即假设的 const 文字会阻止,该语言已经明确禁止:

void foo(int&);
foo(42); // error

但是,该语言没有使42const 成为左值引用,而不是const 不允许绑定到右值。

【讨论】:

【参考方案2】:

请记住,默认情况下 C++ 是传递,这意味着值是复制

没有办法修改像 42 这样的数字文字值,因为您所拥有的只是变量中的副本。文字值本身甚至不必存储在内存中,编译器可以直接在生成的代码中使用它。

【讨论】:

“没有办法修改数字文字值” - 那为什么不是const @IvanRubinson 因为你不能做42 = 5?根本没有必要使数字文字保持不变,因为它们本质上已经是不变的。将数字文字存储在变量中后,您将拥有该数字文字的 副本,您可以根据需要修改该副本,因为它不再是原始文字值。 “没有必要让数字文字保持不变,因为它们本质上已经是” - 这闻起来很腥。如果它本质上是const,为什么不是const @IvanRubinson 看来你没有在听。最后一次,一旦你将一个数字文字值放入一个变量中,它就是你使用的 变量,而不是文字本身!数字文字是prvalue,它们永远不能位于赋值的左侧。您无法获取(指向)数字文字的地址,语言中无法修改。 @IvanRubinson - 因为成为一个纯右值就足够了。它不是一个对象,它只是一个(模糊的)值,可以用来创建一个对象。

以上是关于为啥文字不是 const (字符串除外)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C 字符文字是整数而不是字符?

为啥指针不继承字符串文字的固定大小

为啥修改指向字符串文字的指针的内容是错误的?

可以/为啥在返回类型中使用 char * 而不是 const char * 会导致崩溃?

C 中的字符串文字与 const char*

const char []和const char之间的区别*