C* (Порядок проверки аргументов в операторе if)

Модератор: Модераторы разделов

BratSinot
Сообщения: 812
ОС: Slackware64

C*

Сообщение BratSinot »

Доброго времени суток!

А станадарт C гарантирует порядок вызова функций в выражении? Т.е. если:

Код: Выделить всё

if(f1() || f2())

будет гарантировано вызвана сначала функция f1, а потом f2?

Как-бы "Порядок вычисления подвыражений в выражениях языка С не определен.", в операторах такая-же фигня?
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C*

Сообщение drBatty »

BratSinot писал(а):
28.11.2012 22:30
Как-бы "Порядок вычисления подвыражений в выражениях языка С не определен.", в операторах такая-же фигня?

да.
но тут особый случай: если первый аргумент !=0, то второй НЕ вычисляется. Потому f2() не будет вызвана, если f1() вернёт не ноль. Это относится и к &&, а также к :?

А вот если это *,+,-,*... то выполняются обе функции непонятно в каком порядке.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

BratSinot
Сообщения: 812
ОС: Slackware64

Re: C*

Сообщение BratSinot »

drBatty писал(а):
28.11.2012 23:22
BratSinot писал(а):
28.11.2012 22:30
Как-бы "Порядок вычисления подвыражений в выражениях языка С не определен.", в операторах такая-же фигня?

да.
но тут особый случай: если первый аргумент !=0, то второй НЕ вычисляется. Потому f2() не будет вызвана, если f1() вернёт не ноль. Это относится и к &&, а также к :?

А вот если это *,+,-,*... то выполняются обе функции непонятно в каком порядке.

Хм...., а если функций не две, а n? Там же они могут "по парам" выполниться и потом уже and сделать.

Вообщем от греха подальше сделал:

Код: Выделить всё

 if(f1()) goto ERROR;
 if(f2()) goto ERROR;
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18958
Статус: ✡ иностранный агент
ОС: Debian GNU/Linux

Re: C*

Сообщение Bizdelnick »

(K&R) писал(а):Операторы || выполняются слева направо. Оператор || выдает 1, если по крайней мере один из операндов не равен нулю, и 0 в противном случае. В отличие от |, оператор || гарантирует, что вычисления будут проводиться слева направо: вычисляется первый операнд, включая все побочные эффекты; если он не равен 0, то значение выражения есть 1. В противном случае вычисляется правый операнд, и если он не равен 0, то значение выражения есть 1, в противном случае оно равно 0.
Операнды могут принадлежать разным типам, но операнд должен иметь либо арифметический тип, либо быть указателем. Тип результата - int.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: C*

Сообщение eddy »

Bizdelnick, хорошая цитата. А то частенько народ забывает об этом. Я и сам на такие грабли когда-то наступал: думал, что оба операнда выполнятся. А фигвамушки!
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:

BratSinot
Сообщения: 812
ОС: Slackware64

Re: C*

Сообщение BratSinot »

eddy писал(а):
29.11.2012 00:26
Bizdelnick, хорошая цитата. А то частенько народ забывает об этом. Я и сам на такие грабли когда-то наступал: думал, что оба операнда выполнятся. А фигвамушки!

Главное что они слева направо выполняются.

eddy писал(а):
29.11.2012 00:26
Bizdelnick, хорошая цитата. А то частенько народ забывает об этом. Я и сам на такие грабли когда-то наступал: думал, что оба операнда выполнятся. А фигвамушки!

А я вот никогда так не думал :)
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C*

Сообщение drBatty »

BratSinot писал(а):
28.11.2012 23:24
Хм...., а если функций не две, а n?

если n, то они выполняются слева-направо. Вплоть до первой истинной(в случае, если разделены ||)
или до первой ложной, если разделены &&.

Bizdelnick писал(а):
28.11.2012 23:34
Оператор || выдает 1, если по крайней мере один из операндов не равен нулю

точнее он выдаёт "не ноль", если первый операнд не равен нулю.
если первый операнд равен нулю, то вычисление продолжается, и результат равен нулю, если второй операнд равен нулю и не равен нулю, если второй не равен.

Про единицу я-бы не стал надеяться...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18958
Статус: ✡ иностранный агент
ОС: Debian GNU/Linux

Re: C*

Сообщение Bizdelnick »

drBatty писал(а):
30.11.2012 23:35
точнее он выдаёт "не ноль", если первый операнд не равен нулю.

Кернигану и Ритчи лучше знать. :-)
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C*

Сообщение NickLion »

drBatty писал(а):
30.11.2012 23:35
Bizdelnick писал(а):
28.11.2012 23:34
Оператор || выдает 1, если по крайней мере один из операндов не равен нулю

точнее он выдаёт "не ноль", если первый операнд не равен нулю.
если первый операнд равен нулю, то вычисление продолжается, и результат равен нулю, если второй операнд равен нулю и не равен нулю, если второй не равен.

Про единицу я-бы не стал надеяться...

Bizdelnick прав, такое поведение описано в стандарте. Так что если компилятор возвращает что-то отличное от 0 или 1 (такие есть?), то он нарушает стандарт.
Спасибо сказали:

BratSinot
Сообщения: 812
ОС: Slackware64

Re: C*

Сообщение BratSinot »

NickLion писал(а):
02.12.2012 13:23
Bizdelnick прав, такое поведение описано в стандарте. Так что если компилятор возвращает что-то отличное от 0 или 1 (такие есть?), то он нарушает стандарт.

А в каком стандарте? И какую еденицу он возвращает? В C99 есть булевые типы, а 1 и истина не совсем одно и тоже. Ну на уровне данных ясень пень одно и тоже, но так то нет.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18958
Статус: ✡ иностранный агент
ОС: Debian GNU/Linux

Re: C*

Сообщение Bizdelnick »

BratSinot писал(а):
02.12.2012 15:17
А в каком стандарте?

В процитированной книге описывается ANSI C. Но я сильно сомневаюсь, что в более поздних стандартах это изменилось.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C*

Сообщение NickLion »

BratSinot писал(а):
02.12.2012 15:17
А в каком стандарте? И какую еденицу он возвращает? В C99 есть булевые типы, а 1 и истина не совсем одно и тоже. Ну на уровне данных ясень пень одно и тоже, но так то нет.

Стандарт С99, С11:
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

(остальных под рукой нет, но там тоже что-то аналогичное)
Спасибо сказали: