Оценка короткого замыкания оператора c++ в C
Я выполнил следующий код в Code:: Blocks 10.05 в Windows 7.
int a=0,b=0,c;
c=a++&&b++;
printf("\na=%d\nb=%d\nc=%d\n\n",a,b,c);
Полученный результат я приведен ниже,
a=1
b=0
c=0
Это имеет смысл из-за оценки короткого замыкания.
Выражение a++
- это пошаговое приращение, а 0
возвращается в логическое и (&&
). Следовательно, часть b++
не оценивается, так как и 0 && 0
, и
0 && 1
оценивается как 0
.
Но здесь возникает мое сомнение. Значение приоритета операторов ясно указывает, что ++
имеет более высокий приоритет над &&
. Итак, мое понимание было таким, как оцениваются a++
и b ++, а затем &&
проверяет результат выражения a++
, чтобы прийти к решению. Но этого не произошло, только здесь оценивается a++
.
В чем причина такого поведения? Имеет ли &&
точка последовательности, что-то связано с этим поведением? Если да, то почему мы говорим, что &&
имеет более низкий приоритет, чем ++
?
Ответы
Ответ 1
Вы запутались в приоритете и порядке оценки.
Приоритет определяет, как сгруппированы операторы, т.е.
c = a++ && b++;
эквивалентно:
c = ((a++) && (b++));
Порядок оценки определяет, как оценивается выражение, короткое замыкание &&
означает a++
сначала оценивается, если оно равно нулю, конец; если он не равен нулю, тогда оценивается b++
.
В качестве еще одного примера:
c = (a++) + (b++);
Оценивается a++
до b++
? Ответ в том, что мы не знаем. Большинство операторов не определяют порядок оценки. &&
- один из немногих операторов, которые определяют. (Остальные ||
, ,
и ?:
)
Ответ 2
Здесь есть два понятия - порядок приоритетности и порядок оценки. Порядок приоритета будет иметь влияние только при оценке выражения (или подвыражения).
В общем, порядок оценки не упорядочен. С учетом оператора его операнды могут быть оценены в любом порядке. Аргументы функции могут быть оценены в любом порядке.
Из стандарта С++:
1.9 Выполнение программы
15 За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не подвержены.
и
8.3.6 Аргументы по умолчанию
9 Аргументы по умолчанию оцениваются каждый раз при вызове функции. Порядок оценки аргументов функции не указан.
Для логического оператора И, &&
, в стандарте С++ 11 говорится:
5.14 Логический оператор И
1 Операторы группы &&
слева направо. Операнды преобразуются в контекстном выражении в тип bool
(раздел 4). Результатом является true
, если оба операнда true
и false
в противном случае. В отличие от &
, &&
гарантирует оценку слева направо: второй операнд не оценивается, если первый операнд false
.
Аналогичное исключение указано для логического оператора OR, ||
.
Так как b++
не оценивается из-за короткого замыкания выражения из-за оператора &&
, порядок приоритета операторов не имеет значения в данном конкретном случае.