Как языки справляются с побочными эффектами составных операторов? - PullRequest
8 голосов
/ 14 февраля 2011

Допустим, такая ситуация:

int a = (--t)*(t-2);
int b = (t/=a)+t;

В C и C ++ это неопределенное поведение, как описано здесь: Неопределенное поведение и точки последовательности

Однако, как выглядит эта ситуация:

  • JavaScript
  • Java
  • PHP ...
  • C #
  • ну, а на каком другом языке есть составные операторы?

Я сейчас исправляю порт Javascript -> C ++, в котором это стало незамеченным во многих местах. Я хотел бы знать, как другие языки обычно справляются с этим ... Оставление порядка неопределенным как-то специфично для C и C ++, не так ли?

Ответы [ 4 ]

7 голосов
/ 14 февраля 2011

Согласно спецификации ECMA Script , которая, как я полагаю, должен соответствовать javascript, в выражениях умножения и сложения он оценивает левую часть перед оценкой правой части. (см. 11.5 и 11.6). Я думаю, это означает, что код должен быть эквивалентен

t = t - 1;
int a = t * (t - 2);
t = t / a;
int b = t + t;

Однако не всегда следует полагать, что спецификация совпадает с реализацией!

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

Редактировать: Очевидно, что большинство JavaScript реализует 3-е издание ECMAScript, поэтому вместо этого я изменил ссылку на эту спецификацию.

3 голосов
/ 14 февраля 2011

Практически, если вам нужно спросить или найти правила для выражения, вы не должны использовать это выражение в своем коде. Кто-то еще вернется через два года и поймет неправильно, затем переписает и сломает код.

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

2 голосов
/ 14 февраля 2011

Для javascript следующая статья должна помочь.

В этой статье четко указано, является ли конкретная комбинация

a OP b OP c идет слева направо и в каком порядке.

Я не знаю о других языках.

1 голос
/ 14 февраля 2011

Однако, как выглядит эта ситуация: JS, Java, PHP, C # ...

Если быть абсолютно откровенным, int a = (--t)*(t-2); int b = (t/=a)+t; выглядит как дерьмо.

Приятно иметь модный код, который может быть красивым и элитарным, но в этом нет абсолютно никакой необходимости.Решение для каждого языка, когда вы сталкиваетесь с таким кодом, состоит в добавлении еще пары точек с запятой (если вы не имеете дело с питоном):

--t;
int a = t * (t-2);
t /= a;
int b = t + t;
-or-
int b = t * 2;
-or-
int b = t << 1;
//whichever method you prefer

Если другой порядокоперации желательно, отрегулируйте линии соответственно.Если вы пытаетесь исправить старый ошибочный код, исправьте код , а не просто заново реализуйте чужие спагетти.

Отредактируйте, чтобы добавить:

Я понял, что никогда не отвечал конкретно на оригинальный вопрос:

Как языки справляются с побочными эффектами составных операторов?

Плохо.

...