测序完整性检查

Sequencing sanity check

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

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

由于加法和乘法是交换运算,因此 Pop 调用的计算顺序无关紧要,只要第一个 Pop 调用的副作用(即更新虚拟机的堆栈指针)(无论哪个is) 将在其他 Pop 调用之前完成。

对于减法和除法,顺序确实很重要,所以我们必须确保我们控制先执行哪个 Pop。例如,这里是减法运算的实现:

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

我听说 C++17 收紧了序列点和排序规则,但我没有听到细节。在这方面,我不再是一名语言律师,无法自信地解析规范。

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

没有

其中一个重大变化是对某些运算符(例如移位运算符)进行了从左到右的计算,这会影响流插入。但是 .

老实说,即使情况并非如此,我仍然会推荐您现在拥有的代码,因为它在人类阅读时显然是正确的,依赖于深奥的排序规则永远不会是。