排序健全性检查

时间:2018-12-21 15:27:06

标签: c++ sequence-points

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

    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()调用的顺序及其副作用是已定义,实现定义的还是未指定的?

1 个答案:

答案 0 :(得分:6)

否。

其中一项重大更改是对某些运算符(例如shift运算符)进行了从左到右的评估,这会影响流插入。但是the subtraction operator is not included

老实说,即使情况并非如此,我仍然会推荐您现在使用的代码,因为当人们阅读时,它显然是正确的,而这种方式永远不会依赖深奥的排序规则。