排序健全性检查

Sequencing sanity check

本文关键字:检查 排序      更新时间:2023-10-16

我的问题的上下文是一个简单的基于堆栈的虚拟机的实现。我的加法和乘法运算的实现如下:

case OP_ADD: Push(Pop() + Pop()); break;
case OP_MUL: Push(Pop() * Pop()); break;

由于加法和乘法是交换运算,只要第一个Pop调用(无论是哪一个)的副作用(即更新虚拟机的堆栈指针)将在另一个Pop呼叫之前完成,那么评估Pop呼叫的顺序并不重要。

通过减法和除法,的顺序确实很重要,因此我们必须确保控制先执行哪个Pop。例如,下面是减法运算的实现:

case OP_SUB: {
const auto subtrahend = Pop();
const auto minuend = Pop();
Push(minuend - subtrahend);
break;
}

我听到过一些含糊的说法,说C++17已经收紧了序列点和序列规则,但我没有听到细节。在这方面,我不再是一个足够自信地解析规范的语言律师。

C++17中的变化是否提供了足够的排序保证,使减法可以像加法和乘法一样作为单个表达式来实现?Pop()调用的顺序及其副作用是定义的、实现是定义的还是未指定的?

否。

其中一个很大的变化是对某些运算符,如移位运算符,它们从左到右进行求值,这会影响流插入。但是减法运算符不包括在内。

老实说,即使不是这样,我仍然推荐你现在的代码,因为当人类阅读它时,它显然是正确的,在某种程度上,依赖深奥的测序规则永远不会是正确的。