C++中的字面值真的会被评估吗?

3

我一直以为l-value需要评估,但原因很明显且容易解释。标识符表示存储区域,值在该存储区域中并必须检索。这是有道理的。但是,程序需要评估字面量(例如整数21)对我来说并不太合理。值就在那里,你还能更明确些吗?除了添加U来表示无符号或其他后缀外。这就是为什么我对需要评估字面量感到好奇,因为我只在一个地方看到过这个提到。大多数书籍也会切换术语,如“主要表达式”,“操作数”或“子表达式”等,这使得界限变得模糊。在所有这些时间里,我还没有看到关于这个特定问题的清晰解释。这似乎是浪费处理能力。


1
“我只在一个地方听人提起过这个” - 你介意分享一下吗? - LogicStuff
2
"l-values必须进行评估" 这是什么意思? - juanchopanza
l-values具有可变值,需要检索。 - Arnav Borborah
1
是的,它们确实会被评估。对于像int这样的简单类型,评估只是从保存此变量的内存块中快速移动到寄存器。另外,关于其他问题,切换术语 - 作者们不想含混不清,因此使用语言语法中描述的术语。 - Tomasz Plaskota
2
@j_burks: 你现在在评论中提供的示例是关于表达式的含义。用假设的评估来描述这一点非常方便。这并不意味着机器代码中会发生任何事情,比如根据规范计算值,或者只是从内存中检索一个值到寄存器中。 - Cheers and hth. - Alf
显示剩余7条评论
2个回答

6

普通字面值仅需编译器在编译时进行评估。

用户自定义字面值可能也会在运行时进行评估。例如,包含<string>头文件,并通过指令using namespace std::string_literals;使其...s字面值可用后,"Blah"s是类型为std::string的用户自定义字面值。其中的"Blah"部分由编译器在编译时进行评估。转换为std::string,涉及动态分配,必须在运行时发生。


一个普通的字面量只需要在编译时由编译器进行评估。严格来说,对于浮点类型来说,这并不完全正确。请参见我的回答 - Leon
@Leon:我无法想象每个fp字面量可能有超过两个二进制结果。因此,在编译时生成这两个结果不是问题。在运行时,舍入模式可以在值块之间切换。但由于我没有听说过这样的方案,我认为实际上并没有这样做。 - Cheers and hth. - Alf
用户定义字面量还不是我研究的主题,但我知道它们以及它们的作用。了解字面量是“基本表达式”,并且根据定义表达式“求值”,这使我对此产生了兴趣。但是,如果一个字面量在编译时求值,它仍然在求值,只是不是我想象中的方式。这些小细节并没有在所有书籍中提到,我不喜欢学习错误的信息。就像用手肘弹吉他一样,看起来很酷,但你不能弹奏所有音符或演奏所有歌曲。 - j_burks
@j_burks:我相信 SRV 可以做到。;-) - Cheers and hth. - Alf
@Cheersandhth.-Alf 哈哈!你把我逗笑了,他可能确实可以。 - j_burks

1
“但是我觉得一个程序需要评估一个文字(例如,整数21)有些不太合理。这个值就在那里,你还能更明确吗?”
对于浮点类型来说,情况会稍微复杂一些。考虑数字0.1。在二进制中它无法被准确表示,必须选择最接近的浮点表示。如果您在运行时输入该数字,则必须根据舍入模式(向上、向下、朝零、朝正无穷)进行将0.1转换为二进制表示形式。严格处理浮点运算建议,应该根据舍入模式(仅在运行时才知道)执行将0.1浮点文字转换为二进制表示形式,因此编译器无法完成(实际上它的大部分可以由编译器完成,但最终舍入必须在运行时执行,并考虑到舍入模式)。

1
不强制在运行时完成。C++标准,§2.13.4规定:“...如果缩放值在其类型的可表示值范围内,则结果是缩放值(如果可表示),否则是最接近缩放值的较大或较小可表示值,以实现定义的方式选择...”。这意味着编译器必须记录它是如何完成的,但也可以在编译时完成。 - alain

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