Intereting Posts
Что означает звездочка в спецификаторе формата scanf? Создание для MacOSX, но соединение с dylib, созданное для файла iOS Simulator Как генерировать NaN, -Infinity и + Infinity в ANSI C? Gstreamer1.0: подключить декодеин к видеоконверту Как запустить программу во время прослушивания ввода пользователя в C? Как можно найти с помощью c-программы, будет ли моя машина 16-разрядной или 32-разрядной или 64-разрядной Чтение файлов сертификатов из памяти вместо файла с использованием OpenSSL Как C обрабатывает число 0 в архитектуре комплемента? Почему я получаю ошибку «Ошибка сегментации» при попытке запустить тесты? Предупреждение Valgrind: если я серьезно Valgrind висит в pthread_spin_lock, потребляющем 100% CPU Почему mpirun не уважает мой выбор BTL? Найдите самую длинную повторяющуюся строку и количество повторений в заданной строке Передача выделенного C_PTR массиву Fortran в C std :: bad_alloc после замены boost: shell функции python с API Python / C

Порядок разрешения операндов C и C ++

Много раз я вижу (и иногда пишу) код, похожий на этот пример:

int a=0, b=2; if( a && (b=func())!=0 ) { //... 

Вопрос в том, подтверждает ли стандарт эти утверждения?

  1. b не будет касаться (и останется значением 2 )
  2. func() не будет вызвана

И наоборот, если мы напишем if( func()!=0 && a ) – будет вызвана стандартная гарантия func() ?

Меня интересует конкретный стандартный параграф, определяющий это, является законным.

UPD: моя опечатка, измененная от int a=1 до int a=0

Точный вопрос;

Вопрос в том, гарантирует ли стандарт эти утверждения?

К обновленному вопросу; при a=0 . Если a==0 , то да, оценка короткого замыкания будет вызвана, а func() не будет вызвана; второй операнд не будет оцениваться.

Если a=1 (как было первоначально), наоборот; func() будет вызываться – a равно 1 таким образом, «true», в результате вычисляется второй операнд (это логический И), b будет изменяться. Если бы оператор был || (логическое ИЛИ), то оценка короткого замыкания будет вызвана, а func() не будет вызвана.

И наоборот, если мы напишем if( func()!=0 && a ) – будет ли вызвана стандартная гарантия func() ?

Да, первый операнд всегда оценивается.


Да, оценка короткого замыкания гарантирована для C ++;

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

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

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

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

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

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


Соответствующие кавычки для C:

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

4 В отличие от побитового двоичного оператора, оператор && гарантирует оценку слева направо; если второй операнд оценивается, то существует точка последовательности между оценками первого и второго операндов. Если первый операнд сравнивается с 0, второй операнд не оценивается.

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

4 В отличие от побитового | оператора, || оператор гарантирует оценку слева направо; если второй операнд оценивается, то существует точка последовательности между оценками первого и второго операндов. Если первый операнд сравнивается не равным 0, второй операнд не оценивается.

Из стандарта C-90.

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

….

4 В отличие от побитового двоичного оператора, оператор && гарантирует оценку слева направо; после оценки первого операнда есть точка последовательности. Если первый операнд сравнивается с 0, второй операнд не оценивается.

Аналогично для логического оператора OR.

Оператор && требует, чтобы оба операнда были истинными. Если первый операнд оценивает значение false, то второй операнд не будет оцениваться. Но поскольку a равно 1, оно считается истинным, а второе выражение (операнд) оценивается. Таким образом, func() вызывается и ее результат присваивается b а затем b проверяется на ненулевое значение.

Стандарт гарантирует, что операторы в последовательности && оцениваются слева направо и что, как только один из них оценит значение false, те, которые справа от него, не будут оценены.

Вопрос в том, гарантирует ли стандарт эти утверждения?

b не будет касаться (и останется значением 2)

Функция func () не будет вызвана

Нет, на самом деле оба они ошибаются в этом случае. Потому что это оператор && поэтому в этом конкретном случае не может быть применена логика ярлыков.

Если вы измените его на || то ваши утверждения верны – только тогда оценка первого операнда ( a = 1 в этом случае) будет достаточной, а остальная часть будет проигнорирована.


Когда вопрос изменился на a = 0 тогда да, оба утверждения правильны и гарантированы.