Логические операции: поведение компилятора
От: ser_gunya  
Дата: 06.10.07 13:08
Оценка: :)
Добрый день.
Столкнулся вот с чем:
bool b = false;
int i = 0;
b &= (1 == i++);

и
bool b = false;
int i = 0;
b = false && (1 == i++);

Почему в первом случае правый операнд высчитывается в любом случае?
Это поведение компилятора(VC) или как?
Спасибо
Re: Логические операции: поведение компилятора
От: Andrew S Россия http://alchemy-lab.com
Дата: 06.10.07 13:18
Оценка:
_>Добрый день.
_>Столкнулся вот с чем:
_>
_>bool b = false;
_>int i = 0;
_>b &= (1 == i++);
_>

_>и
_>
_>bool b = false;
_>int i = 0;
_>b = false && (1 == i++);
_>

_>Почему в первом случае правый операнд высчитывается в любом случае?

Потому что приведенный код — не эквивалентен. В первом случае побитовое and, а во втром — логическое.

_>Это поведение компилятора(VC) или как?


Это у вас недопонимание базовых конструкций языка ...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Логические операции: поведение компилятора
От: ser_gunya  
Дата: 06.10.07 14:06
Оценка:
Здравствуйте, Andrew S:

Спасибо
Re: Логические операции: поведение компилятора
От: ilnar Россия  
Дата: 06.10.07 14:19
Оценка:
Здравствуйте, ser_gunya, Вы писали:

_>Добрый день.

_>Столкнулся вот с чем:
_>
_>bool b = false;
_>int i = 0;
_>b &= (1 == i++);
_>

_>и
_>
_>bool b = false;
_>int i = 0;
_>b = false && (1 == i++);
_>

_>Почему в первом случае правый операнд высчитывается в любом случае?
_>Это поведение компилятора(VC) или как?
_>Спасибо

гарантируется сокращенное вычисление только логических выражений.
первое выражение у вас не логическое
Re: Логические операции: поведение компилятора
От: diatlov Молдова  
Дата: 06.10.07 15:14
Оценка: -2
Здравствуйте, ser_gunya, Вы писали:

_>Добрый день.

_>Столкнулся вот с чем:
_>
_>bool b = false;
_>int i = 0;
_>b &= (1 == i++);
_>

_>и
_>
_>bool b = false;
_>int i = 0;
_>b = false && (1 == i++);
_>

_>Почему в первом случае правый операнд высчитывается в любом случае?
_>Это поведение компилятора(VC) или как?
_>Спасибо

Потому что во втором случае логическое выражение. Для логических выражений, если внутри бинарного AND первый оператор ЛОЖЬ, то дальнейшие вычисления компилятор не производит а сразу пишет в переменную ЛОЖЬ (т.к. это и ежу понятно, что там всегда ЛОЖЬ будет ).
Все эти дела — последствия оптимизации. На некоторых других компиляторах с выключенной оптимизацией оба примера ведут себя эквивалентно.
Re[2]: Логические операции: поведение компилятора
От: Andrew S Россия http://alchemy-lab.com
Дата: 06.10.07 15:58
Оценка:
D>Потому что во втором случае логическое выражение. Для логических выражений, если внутри бинарного AND первый оператор ЛОЖЬ, то дальнейшие вычисления компилятор не производит а сразу пишет в переменную ЛОЖЬ (т.к. это и ежу понятно, что там всегда ЛОЖЬ будет ).

D> Все эти дела — последствия оптимизации. На некоторых других компиляторах с выключенной оптимизацией оба примера ведут себя эквивалентно.


Это не так. Если binary (в смысле количество операндов) логический оператор (в данном случае logical and) не переопределен, то его аргументы вычисляются слева направо и имеет место "ленивое" вычисление (т.е. если значение операции уже определено левой частью, правую вычислять не надо — см. стандарт).
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Уточню...
От: Erop Россия  
Дата: 07.10.07 10:33
Оценка:
Здравствуйте, diatlov, Вы писали:

D> Все эти дела — последствия оптимизации. На некоторых других компиляторах с выключенной оптимизацией оба примера ведут себя эквивалентно.


1) В большнстве случаев оптимизатору запрещено изменять видимое поведение однопоточной программы (исключения редкие, и в основном связаны с экономией вызовов конструкторов копирования)
2) При любом уровне оптимизации можно писать так:
MyObj* obj = getObj();
if( obj != 0 && obj->IsValid() ) {  // Даже при obj == 0 AV никогда не будет!!!
    process( obj );
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Логические операции: поведение компилятора
От: Кодт Россия  
Дата: 08.10.07 09:47
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Это не так. Если binary (в смысле количество операндов) логический оператор


Для разруливания этой неоднозначности в русском языке есть слово "двухместный" — заведомо относящийся к арности, а не к домену операции (булевой алгебре над false,true или над целыми числами как битовыми векторами).
Извиняюсь за my french — слова "арность" и "домен". Забыл, как их кличут в русской традиции.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: Логические операции: поведение компилятора
От: ser_gunya  
Дата: 11.10.07 14:38
Оценка:
Всем спасибо за разъяснения, я все понял и покаялся.
Но вот беда, я привык писать конструкции такого вида:
bool result = false;
result = _реультат_какой-то_операции_;
result &= _результат_какой-то_операции_;
...
result &= _результат_какой-то_операции_;

Заменить её на
bool result = false;
result = _результат_какой-то_операции_;
result = result &&_результат_какой-то_операции_;
...
result = result && _результат_какой-то_операции_;

или
bool result = false;
result = _результат_какой-то_операции_;
if(result)
  result = result && _результат_какой-то_операции_;
...
if(result)
  result = result && _результат_какой-то_операции_;

некрасиво.
Операции "&&=" как я понимаю нету в С++.
Как быть, поделитесь советом.
Спасибо
Re[2]: Логические операции: поведение компилятора
От: Erop Россия  
Дата: 11.10.07 15:10
Оценка:
Здравствуйте, ser_gunya, Вы писали:
SG> Но вот беда, я привык писать конструкции такого вида:
Лучше пиши такого:
bool result = false;
result = _результат_какой-то_операции_;
if(result)
  result = _результат_какой-то_операции_;
...
if(result)
  result = _результат_какой-то_операции_;


Если тебе нравится непонятный и запутанный код, то...
Второй вариант такой:
#define SET_IF( flag ) if( !(flag) ) else ( flag )  
#define SET_IF_NOT( flag ) if( flag ) else ( flag )

Ну и пишешь себе:
bool result = true;
SET_IF( result ) = _результат_какой-то_операции_;
SET_IF( result ) = _результат_какой-то_операции_;
...
SET_IF( result ) = _результат_какой-то_операции_;


Хотя, конечно,
#define SET_IF( flag, expr ) if( !(flag) ) else ( flag ) = expr
#define SET_IF_NOT( flag, expr ) if( flag ) else ( flag ) = expr

Выглядят традиционнее и понятнее...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Логические операции: поведение компилятора
От: Sergey Chadov Россия  
Дата: 11.10.07 16:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Извиняюсь за my french — слова "арность" и "домен". Забыл, как их кличут в русской традиции.

Так и говорят "арность" или иногда "местность". А domain это область определения
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.