Последовательность проверки работоспособности - PullRequest
0 голосов
/ 21 декабря 2018

Контекст моего вопроса - реализация упрощенной виртуальной машины на основе стека.Моя реализация операций сложения и умножения выглядит следующим образом:

    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 голосов
/ 21 декабря 2018

Нет.

Одно из больших изменений коснулось некоторых операторов, таких как операторы сдвига, которые оцениваются слева направо, и это влияет на вставку потока.Но оператор вычитания не включен .

И, честно говоря, даже если бы это было не так, я все равно рекомендовал бы код, который у вас есть сейчас, потому что он явно корректен при чтениичеловеческим способом, который никогда не будет основываться на эзотерических правилах секвенирования.

...