Оценка короткого замыкания оператора с оператором ++ в 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++.

В чем причина такого поведения? Имеет ли отношение к такому поведению && как точка следования? Если да, то почему мы говорим, что && имеет более низкий приоритет, чем ++?


person Deepu    schedule 03.08.2015    source источник
comment
над ними есть еще одно правило: a++ будет увеличиваться только после выполнения оператора. Таким образом, каким бы ни был его приоритет, он будет увеличиваться после завершения утверждения.   -  person saurabh agarwal    schedule 03.08.2015
comment
Вау, это неприятная ловушка.   -  person Ignacio Vazquez-Abrams    schedule 03.08.2015
comment
Помимо интересных языковых аспектов этого вопроса, я бы рекомендовал сделать ваш код сразу разборчивым и очевидным. В настоящее время это не так.   -  person Lee Taylor    schedule 03.08.2015
comment
Я думаю, что это грустно, что такой код получает ЛЮБЫЕ голоса.   -  person Martin James    schedule 03.08.2015
comment
@saurabhagarwal a++ будет увеличиваться в неопределенное время между моментом оценки a и завершением оператора. Вот почему вы не можете снова использовать a в одном и том же выражении (до или после a++).   -  person Potatoswatter    schedule 03.08.2015
comment
Честно говоря, мне грустно, что два человека жалуются на код вместо того, чтобы редактировать сообщение. (Чтобы избежать очевидных ответов: я оставлю украшательство людям, которые действительно работают с языком.)   -  person Lilienthal    schedule 03.08.2015


Ответы (2)


Вы не понимаете приоритет и порядок оценки.

Приоритет определяет, как сгруппированы операторы, т.е.

c = a++ && b++;

эквивалентно:

c = ((a++) && (b++));

Порядок оценки определяет, как оценивается выражение, короткое замыкание && означает, что a++ оценивается первым, если оно равно нулю, то в конце; если он не равен нулю, тогда оценивается b++.


В качестве другого примера:

c = (a++) + (b++);

Оценивается ли a++ перед b++? Ответ - мы не знаем. Большинство операторов не определяют порядок оценки. && — один из немногих операторов, которые определяют. (Остальные ||, , и ?:)

person Yu Hao    schedule 03.08.2015
comment
Другой способ сказать это состоит в том, что && определяет точку следования после оценки своего левого аргумента и перед вычислением второго аргумента. Для + не определена точка последовательности. В Википедии есть хорошая статья о точках последовательности. - person martinkunev; 03.08.2015

Здесь есть два понятия — порядок старшинства и порядок оценки. Порядок приоритета будет иметь значение, только если вычисляется выражение (или подвыражение).

Как правило, порядок оценки не является последовательным. Учитывая оператор, его операнды могут быть оценены в любом порядке. Аргументы функции можно вычислять в любом порядке.

Из стандарта С++:

1.9 Выполнение программы

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

и

8.3.6 Аргументы по умолчанию

9 Аргументы по умолчанию оцениваются каждый раз при вызове функции. Порядок оценки аргументов функции не указан.

Для логического оператора И, &&, стандарт С++ 11 говорит:

5.14 Логический оператор И

1 Оператор && группирует слева направо. Оба операнда контекстно преобразуются в тип bool (раздел 4). Результатом является true, если оба операнда равны true и false в противном случае. В отличие от &, && гарантирует вычисление слева направо: второй операнд не оценивается, если первый операнд равен false.

Аналогичное исключение указано для логического оператора ИЛИ, ||.

Поскольку b++ не оценивается из-за короткого замыкания выражения из-за оператора &&, порядок приоритета операторов не имеет значения в данном конкретном случае.

person R Sahu    schedule 03.08.2015
comment
говоря, что порядок приоритета сбивает с толку проблему, порядок оценки и приоритет должны быть разделены - person M.M; 04.08.2015