В java вы получаете гарантию, что всегда будете наблюдать этот код, выводящий First
, и никогда Second.
В C / C ++ вы не получите таких гарантий. В зависимости от компилятора, архитектуры, ОС и фазы луны он, скорее всего, напечатает только First
или Second
, но я почти уверен, что C и C ++ spe c делают его «законным» для compiler / architecture / OS / phase-of-moon combo для вывода ОБЕИХ First
и Second
или даже ни одного.
См. порядок оценки правила для C ++: Учитывая некоторые Конструкция бинарного оператора: a x b
, где a и b - выражения, а x - некоторый бинарный оператор, тогда сначала должны быть вычислены a
и b
, а затем оператор x
применяется к полученным таким образом значениям. Если оператор явно не определяет порядок (что, например, делают операторы ||
и &&
; они обещают выполнить короткое замыкание, то есть вообще не вычислять b
, если a
такое, что b не может повлиять на результат) - тогда компилятор C (++) может выдавать такой код, что b
оценивается раньше, чем a
, или наоборот.
C заполнено до краев с такими «musts» и «mays»: C spe c разработан для того, чтобы код C мог компилироваться на широком спектре микросхем с огромной свободой действий для компилятора для применения далеко идущих оптимизаций. Дошло до того, что простые примитивные типы данных имеют неопределенную битовую ширину.
В отличие от java, где почти все заблокировано: очень мало аспектов кода java, которые намеренно оставлены неопределенными, и компилятор находится «на рельсах» и очень сильно ограничен в том, какой байт-код ему разрешено генерировать (в java, оптимизации оставлены компилятору времени выполнения / хотспот, а не javac
).
Вот почему на java spe c DOES явно определяет, как a x b
должно быть разрешено: java spe c определяет, что независимо от оператора, a
всегда должен оцениваться до вычисления b
(если, как и в C, b вообще не оценивается из-за правил короткого замыкания).
Возвращение к Java Спецификация языка v7, SPE c явно диктует, что левая часть ДОЛЖНА быть оценена первой - и с тех пор это не изменилось (и я почти уверен, что так было с java 1.0, чего это стоит. Вероятно, это глава 15.7.1 в большинстве версий JLS).