рассмотрим этот код (C ++):
int x = -4 , y = 5 ;
bool result = x > 0 && y++ < 10 ;
выражение (x> 0) будет вычислено первым, и потому что (x> 0 = false) и из-за оценки короткого замыкания, другое выражение (y ++ < 10) не будет оцениваться и значение у останется 5.
Теперь рассмотрим следующий код:
int x = -4 , y = 5 ;
bool result = (x > 0) && (y++ < 10) ;
Ожидается, что выражения в скобках будут оцениваться в первую очередь, так что перед выполнением логического И выражение (y ++) < 10) была бы оценена и значение у стало 6
, но реальность такова, что значение у остается 5. Это означает, что даже с круглыми скобками оценка закорочена и выражение (y ++ < 10) игнорируется.
Чем объясняется этот случай ?!
Объяснение в вопросе — короткое замыкание.
В C ++ оценка &&
(а также ||
в этом отношении) гарантированно будет слева направо, и как только false
встречается (соответственно true
за ||
), оценка гарантированный прекратить.
Похоже на Java.
Скобки в этом случае избыточны и не имеют отношения к делу — они не имеют ничего общего с приоритетом оператора. Это просто связано с тем, как &&
работает:
На самом деле, две версии
x > 0 && y++ < 10
(x > 0) && (y++ < 10)
эквивалентны, потому что ++
имеет наивысший приоритет, затем <,>
, и наконец &&
, Педантично, вы должны были написать это как:
(x > 0) && ((y++) < 10)
1
&&
оператор группы слева направо. Оба операнда неявно преобразуются в тип bool (пункт 4). Результат
верно, если оба операндаtrue
а такжеfalse
иначе. В отличие от &, && гарантирует оценку слева направо: второе
операнд не оценивается, если первый операндfalse
, (акцент мой)
Когда левая сторона определяет результат, правая сторона не оценивается.
В первом случае правая сторона y++ < 10
и это не оценивается. Во втором случае правая сторона (y++ < 10)
и это не оценивается.
Нет правила, что выражения в скобках вычисляются первыми. Скобки только групповые операнды.
Даже с круглыми скобками должен все еще состоится. Подумайте, есть ли у вас выражение с указателями:
int* ptr = 0;
int bar = 5;
bool result = (ptr != 0) && (*ptr == bar || bar > 10);
Вы явно не можете безопасно оценить правую часть &&
там, но скобки требуются, чтобы сделать приоритетность работы, как предполагалось. Скобки просто определяют порядок операций которые на самом деле выполняются не то, что они происходят в определенном порядке.