LINUX.ORG.RU

[c/c++] логические операции. Они ленивые?


0

2
if (firstBoolFunc() || secondBoolFunc()) {
    // ...
}

Если firstBoolFunc() возвращает true, будет ли выполняться secondBoolFunc()?

Касается ли это прочих случаев (||, &=, |=)?

★★★★★

Последнее исправление: Obey-Kun (всего исправлений: 1)
Ответ на: комментарий от unsigned

Я про

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

...

В языке «C», как и в большинстве языков, не фиксируется порядок вычисления операндов в операторе.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Читайте стандарт, а не чьи-то бредни.

ISO/IEC 9899:1999 (E)

6.5.13 Logical AND operator

4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares equal to 0, the second operand is not evaluated.

6.5.14 Logical OR operator

4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.

akk ★★★★★
()
Ответ на: комментарий от Eddy_Em

Повторюсь, это поведение чуть старше, чем C. В K&R это должно быть.

unsigned ★★★★
()
#include <iostream>

bool firstBool(bool value)
{
    std::cout << "First bool." << std::endl;
    return value;
}

bool secondBool(bool value)
{
    std::cout << "Second bool." << std::endl;
    return value;
}

int main(int argc, char *argv[])
{
    if (firstBool(true) || secondBool(false)) std::cout << "OR done." << std::endl;
    if (firstBool(false) && secondBool(true)) std::cout << "AND done." << std::endl;
    return 0;
}

gcc показывает, что ленивые:

First bool.
OR done.
First bool.
Genuine ★★★
()
Ответ на: комментарий от stevejobs

>там в стандарте дофига мест «на усмотрение реализаторов».

Но только не порядок выражений в &&, ||.

Dimanc ★★
()
Ответ на: комментарий от hdfan2

>Кстати, даже если вычисления ленивые, то не факт, что сначала вычислится firstBoolFunc(), а не secondBoolFunc().

if (firstBoolFunc())

func();


else if (secondBoolFunc())


func();



Еще один! Да когда же вас всех перебьют тяжелой заточенной лопатой.

Dimanc ★★
()
Ответ на: комментарий от anonymous

выражение 4 + 5 + 8 - 4

может перегруппировать и считать так если это эффективней 4 - 4 + 5 + 8

(нельзя даже знать что будет первое сложение или вычитание не то что порядок вычисления операндов одной операции)

anonymous
()
Ответ на: комментарий от anonymous

это как раз то о чем писал Eddy_Em

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

anonymous
()
Ответ на: комментарий от Dimanc

> Еще один! Да когда же вас всех перебьют тяжелой заточенной лопатой.
Злые вы. Зачем сразу лопатой? А ошибку признаю, да. Зато радует, что говнокод не потребуется

hdfan2
()
Ответ на: комментарий от Rastafarra

Спасибо за наводку, кажется, это очень неплохая книга!
плюс в карму.

Tweaker ★★★★☆
()
Ответ на: комментарий от Rastafarra

а как же мифы и предания? черная книга? книга дракона? книга, которая не лезет ни на одну полку?

у меня есть стандарт Haskell98, распечатанный собственноручно и подшитый в полиграфии в твёрдый чёрный переплёт без заглавия - я ласково называю его некрономиконом

jtootf ★★★★★
()

На сколько я знаю gcc самый правильный из всех (если это не так пожалуйста поправте!) и как мне кажется это логично чтобы эти операции были ленивыми(зачем перегружать ненужным). Если в gcc лень значит и везде должна быть лень... Я полагаю, что если нужно выполнить обязательно обе функции, это стоит сделать до проверки и просто запомнить результаты (пусть это и глупо, но делать проверку 2 операнда && при первом false еще глупее).

mrcim
()
Ответ на: комментарий от mrcim

>На сколько я знаю gcc самый правильный из всех

Нет, неверно. В gcc много нестандартных расширений, а его поведение в местах, которые в стандарте не прописаны не совпадает с поведением других компиляторов.

Если в gcc лень значит и везде должна быть лень...


Нет.

Но стандарт и K&R вообще говорит о строгой проверке слева направо, которая продолжается только при необходимости.

Dimanc ★★
()
Ответ на: комментарий от Dimanc

Хех тогда почему gcc не самый близкий к стандартам?)

mrcim
()

Я бы не стал проверять второй параметр, а ты?)

mrcim
()
Ответ на: комментарий от Eddy_Em

Вы совершенно зря спорите. Речь идёт о &&, ||, ?:. Они не простые операторы и их поведение существенно отличается от поведения остальных, о чём кстати написано в стандарте. Такой вот он C++.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

И много получилось (по размеру)?

средней толщины книга формата A4; тяжеловата, но сугубо из-за переплёта

вообще - один из самых приятных стандартов на ЯП, которые доводилось читать

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Мне просто он казался довольно маленьким для книги формата A4. Впрочем я видел его только в интернете и вроде бы 2010ый.

KblCb ★★★★★
()
Ответ на: комментарий от jtootf

> у меня есть стандарт Haskell98 [...] - я ласково называю его некрономиконом

ну так форсить надо.

Rastafarra ★★★★
()
Ответ на: комментарий от hdfan2

Так говнокод бы ни в каком случае не понадобился, вне зависимости от того, в каком порядке аргументы вычисляются.

anonymous
()
Ответ на: комментарий от nanonymous

Спасибо, я уже разобрался. Не гарантирован порядок булевых операций & и |, а порядок логических && и ||, оказывается, еще со времен древнего С гарантирован...

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.