David Elkind ([info]disbalanced) wrote,
@ 2008-12-22 14:15:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Current mood: amused
Current music:King Crimson -In the Wake of Poseidon

От перестановки слагаемых сумма не меняется
Чем отличаются результаты исполнения двух нижеприведённых кусков кода? Ответы скринятся.


boolean processed = false;
for (int j = 0; j < processors.length; ++j)
{
    processed = processed || processors[j].process();
}

и

boolean processed = false;
for (int j = 0; j < processors.length; ++j)
{
    processed = processors[j].process() || processed;
}




(17 comments) - (Post a new comment)


[info]doresh_tziyon
2008-12-22 12:26 pm UTC (link)
Дык второй фрагмент вызовет process() на всех элементах массива, а первый будет вызывать process() только до тх пор, пока первый раз не получит true в ответе.

(Reply to this) (Thread)


[info]disbalanced
2008-12-22 12:28 pm UTC (link)
Йес! 2 часа работы ушло погулять :)

(Reply to this) (Parent)

Скоростью
[info]urva_parah
2008-12-22 12:34 pm UTC (link)
В первом случае после нахождения одного True, во всех следующих витках for, OR не будет выполняться

(Reply to this) (Thread)

Re: Скоростью
[info]disbalanced
2008-12-22 12:46 pm UTC (link)
Верно!

(Reply to this) (Parent)

Re: Скоростью
[info]disbalanced
2008-12-22 02:57 pm UTC (link)
Кстати, не только скоростью, но и побочным эффектом. В моём случае в этом и была проблема.

(Reply to this) (Parent)


[info]zyama_krendel
2008-12-22 12:36 pm UTC (link)
Ещё как меняется. :)

Я бы, кстати, после первого true, возвёрнутого функцией, просто вывалился бы из цикла. Тогда даже флага не нужно. ;)

(Reply to this) (Thread)


[info]disbalanced
2008-12-22 12:47 pm UTC (link)
Это был баг в коде. Я его искал 2 часа. Правда, без дебаггера - код бежит в недебаггируемом окружении :). Мне было нужно как раз чтобы все процессоры отработали.

(Reply to this) (Parent)(Thread)


[info]zyama_krendel
2008-12-22 12:49 pm UTC (link)
Ясно... да, бывает. Ещё из той же серии практически необнаруживаемых, даже с дебаггером багов:

a =- 5;

(вместо a -= 5).

(Reply to this) (Parent)(Thread)


[info]disbalanced
2008-12-22 01:01 pm UTC (link)
Не совсем из той же.. Здесь просто описка, тогда как в моём примере речь идёт о разнице между свойством логического оператора ИЛИ (симметричность) и побочным эффектом эвалюации этого логического оператора в программе (каковой продиктован исключительно соображениями оптимизации). Я представляю себе компилятор, в котором такой код будет работать по-разному в дебаг и релиз билдах... Вот это - настоящий кошмар.

(Reply to this) (Parent)(Thread)


[info]zyama_krendel
2008-12-22 01:04 pm UTC (link)
Не, ну тогда на таком языке и писать нельзя... Уж такие вещи точно должны быть однозначно определены.

(Reply to this) (Parent)(Thread)


[info]disbalanced
2008-12-22 02:37 pm UTC (link)
Согласен. Мне, кстати, нравится подход Ады - там есть на каждый логический оператор ДВА оператора - один из которых всегда делает эвалюацию до конца (то есть, является точным воспроизведением математических свойств оператора).

(Reply to this) (Parent)(Thread)


[info]zyama_krendel
2008-12-22 02:40 pm UTC (link)
Тоже выход. Но во всех языках, поддерживающих синтаксис из вашего примера (C-like syntax), действует именно то правило, которое я описал.

(Reply to this) (Parent)(Thread)


[info]disbalanced
2008-12-22 02:47 pm UTC (link)
В C++ с этим вообще бардак будет, из-за перегруженных операторов. Ведь если я перегружу двухсторонний оператор, он превратится в функцию (например, operator||(MyClass& a, MyClass& b)), то есть, при вызове его будет сделана эвалюация как правой так и левой части, по понятным причинам. Таким образом, эвалюция по мере необходимости для встроенных типов создаст там тот ещё бардак...

(Reply to this) (Parent)

(Deleted post)

[info]disbalanced
2008-12-22 02:58 pm UTC (link)
http://disbalanced.livejournal.com/41131.html?thread=424619#t424619

(Reply to this) (Parent)


[info]zyama_krendel
2008-12-22 12:39 pm UTC (link)
Ах, они скринятся... :) Ну ясное дело, в определении языка так и написано: логические выражения эвалюируются слева направо, и как только полученные данные позволяет однозначно заключить, какой будет ответ, эвалюация прекращается. Следовательно, если флаг стоит первым, то первый же processor, который вернёт true, станет единственным сработавшим processor'ом, а если вторым - то запущену будут ВСЕ processor'ы, а флаг в конце, максимум, скажет, вернул ли вообще кто-то true.

(Reply to this)


[info]rev_andre
2008-12-22 12:40 pm UTC (link)
Надо думать, количество вызовов "processors[j].process()" может кардинально не совпадать. Весьма классический баг - в общем, так писать не надо.

(Reply to this) (Thread)


[info]disbalanced
2008-12-22 12:48 pm UTC (link)
http://disbalanced.livejournal.com/41131.html?thread=422827#t422827

(Reply to this) (Parent)


(17 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…