C++表达式求值:底层发生了什么?

5
我仍在学习C++。我试图以逐步的方式理解评估是如何进行的。所以,使用这个简单的例子,一个表达式语句: ``` int x = 8 * 5 - 5; ```
以下是我认为发生的事情。请告诉我我有多远离正确: 1. 操作数x, 8, 5和5被 "评估"。可能会创建临时对象来保存每个值(我不太确定)。 2. 8 * 5评估为40,并存储在临时变量中。 3. 40(临时)- 5评估为35(另一个临时)。 4. 35被复制到x。 5. 所有临时对象按创建顺序相反的顺序被销毁(值被丢弃)。
我至少接近正确吗?

4
从非常高层次的角度来看,是的。但实际上,操作是在CPU寄存器中执行的。在真正的现实中,整个表达式在编译时就被计算出来了,所以你最终编译的只是“x=35”。 - Sam Varshavchik
让我找到那个问题,将其标记为重复... - Jean-François Fabre
@SamVarshavchik 谢谢您,先生。嗯,如果所有的操作数都是命名对象而不是文字常量,会发生什么呢?它会即时创建临时对象,而不是在编译时创建吗? - Alfred Oswald
在第一步中,左侧的x不会被评估,因为它不是一个操作数。它只会成为类似于'+='的快捷操作符的操作数。 - milbrandt
1个回答

0
“谢谢您,先生。嗯,如果所有的操作数都是命名对象而不是文字,会怎么样呢?会即时创建临时变量,而不是在编译时创建吗?”
就像Sam提到的那样,从高层次上来说,您是正确的。 如果是第一个例子,它将使用CPU寄存器来存储临时变量(因为它们不是命名对象),如果它们是命名对象,则取决于设置在编译器上的优化标志和代码的复杂性,以确定生成的代码有多“优化”。 可以查看反汇编结果来真正了解发生了什么。 例如,如果您执行...
a = 5;
b = 2;
c = a * b;

编译器会尝试生成最优代码,因为在这种情况下有两个常量在编译时已知,并且您进行了乘以2的操作,它将能够采取捷径,有时乘法会被更便宜的位操作替换(乘以2相当于将1向左移动)

命名变量必须存在某个地方,可以是堆栈或堆上,并且CPU将使用命名对象的地址来传递它们并执行函数。 (如果它们足够小,则将适合寄存器并对其进行操作,否则它将开始使用内存,首先是缓存,然后流出到RAM)

您可以搜索“抽象语法树”以了解可读性良好的C ++代码如何转换为机器代码。

这就是为什么学习const正确性,别名和指针与引用非常重要,以确保您为编译器提供了生成最佳代码的最佳机会。 (除了用户从中获得的优势之外)


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