- 1
mExpanded = onExpandClick ? !mExpanded : mExpanded;
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+1009
mExpanded = onExpandClick ? !mExpanded : mExpanded;
Lure Of Chaos 22.02.2012 22:21 # 0
им бы дать волю, они бы и циклы и сложения тернарным бы записывали
zooz13 22.02.2012 22:52 # +1
defecate-plusplus 22.02.2012 23:46 # +5
Говногость 23.02.2012 00:37 # 0
zooz13 23.02.2012 00:40 # 0
Говногость 23.02.2012 00:53 # 0
Ох, если бы так... ^^
http://ideone.com/nOjUL
zooz13 23.02.2012 01:21 # 0
Говногость 23.02.2012 01:43 # +1
Таже визуал студия за такое выдаст performance warning, затребовав вместо if(a^b) написать if((a^b)!=0)
Логические операции то не просто так придумали.
Steex 23.02.2012 04:28 # 0
TheCalligrapher 23.02.2012 05:10 # +2
Через '!=' правильнее будет '!a != !b'. Это - логический xor. Но такой вариант, к сожалению, не создает точки следования между операндами (как это делают '&&' и '||).
Поэтому еще правильнее может быть '(!a && b) || (!b && a)'. Но этот вариант, к сожалению, страдает множественным вычислением операндов.
Что делать? А вот что: 'a ? !b : b'. Это - логический xor с точкой следования внутри и одноразовым вычислением операндов.
Не узнаете? Смотрим на код исходного автора и понимаем, что человек, вполне возможно, руководствовался вполне здравыми соображениями.
Говногость 23.02.2012 09:56 # 0
А чем это грозит? Порядок вычисления операндов не определён?
> 'a ? !b : b'. Это - логический xor с точкой следования внутри и одноразовым вычислением операндов.
b разве 2 раза не вычисляется?
TheCalligrapher 23.02.2012 10:52 # +3
Например, если кто-то определил макро 'XOR(a, b)' как '(!(a) != !(b))', то выражение 'XOR(i++, i)' будет порождать неопределенное поведение. А если макро определено как '((a) ? !(b) : (b))', то поведение определено, первый операнд гарантированно вычисляется до второго и их вычисление разделено точкой следования.
Одним из свойств оператора '?:' является то, что он вычисляет одну и только одну из своих условных подветок. Поэтому в данном определении операнд 'b' вычисляться будет строго один раз и строго после вычисления 'a'.
Говногость 23.02.2012 10:59 # 0
gegMOPO4 23.02.2012 21:42 # 0
TheCalligrapher 24.02.2012 00:18 # −2
absolut 24.02.2012 09:00 # +1
TheCalligrapher 24.02.2012 09:55 # 0
absolut 24.02.2012 14:00 # 0
guest 06.03.2012 14:54 # −2
absolut 06.03.2012 15:42 # +1
TheCalligrapher 14.03.2012 01:25 # 0
gegMOPO4 24.02.2012 12:45 # 0
gegMOPO4 24.02.2012 12:44 # 0
Говногость 23.02.2012 10:36 # 0
Что это? Бред или так и есть?
Говногость 23.02.2012 10:56 # 0
>Несколько присваиваний подряд
Интересный момент с таким кодом:
int a=1, b=2, c=3;
a=b=c=0;
Стандарт как-то очень нечетко описывает такую ситуацию. Он говорит, что операция должна происходить справа налево, но ничего не говорит дополнительно по поводу того, когда должен быть результат этой операции записан в переменную. Точек следования внутри выражения нет, что значит, что компилятор может теоретически творить здесь что угодно и не обязательно все переменные в итоге будут равны 0. Так что, опять же теоретически, здесь имеет место unspecified behavior.
wvxvw 23.02.2012 13:46 # 0
bugmenot 23.02.2012 13:51 # +3
звучит даже лучше, чем Майя Lucidfox
Говногость 23.02.2012 13:54 # 0
gegMOPO4 23.02.2012 21:44 # 0
TheCalligrapher 23.02.2012 11:11 # +3
В реальности же 'a = b = 1' означает комбинацию 'b = 1' и 'a = (type_of_b) 1'. Т.е. оба присваивания в данном случае делаются независимо и не используют переменную 'b' в качестве "посредника". Никакой неопределенности тут нет.
Говногость 23.02.2012 11:22 # 0
Впрочем, я с вами соглашусь. Похоже на бред.
Говногость 23.02.2012 10:49 # 0
То есть точка следования между этими операторами пропадает после перегрузки этих операторов? То есть порядок вычисления аргументов этих операторов не определён? То есть уходит ленивость этого оператора? Что-за крестопроблемы... >_>
gegMOPO4 23.02.2012 21:45 # 0
Говногость 23.02.2012 22:12 # 0
Кстати a , b активно используется в BOOST::ASSIGN. Все же перегрузка полезная.
Перегрузка операторов
a || b
a && b
нужна для создания своей обертки над bool или своих булевых алгебр, например BOOST::TRIBOOL. Тоже полезная перегрузка.
gegMOPO4 23.02.2012 22:23 # +1
Сейчас же перегруженные || и && теряют свою семантику (превращаясь в | и &). Поэтому лучше их никогда-никогда не использовать.
TarasB 24.02.2012 10:02 # 0
roman-kashitsyn 24.02.2012 10:59 # 0
SmackMyBitchUp 24.02.2012 12:30 # +1
roman-kashitsyn 24.02.2012 12:37 # 0
Мне вот, к примеру пришлось недавно на жабе метод написать, который берёт список объектов, разбивает их на пары и попарно сравнивает (null-безопасным сравнением). Возвращает true, если объекты в парах равны. Проблемы начинаются, когда в метод нужно передавать объекты, являющиеся результатом вычислений. Если вычисления ресурсоёмкие (а такое бывает довольно часто), а сравнение прекратится до того момента, как дело дойдёт до результатов долгих вычислений, много тактов будет потрачено впустую.
в лиспе для оптимизации можно использовать простенький макрос, в хаскеле же практически любая чистая функция, реализующая этот функционал, будет работать правильно автоматически.
SmackMyBitchUp 24.02.2012 13:01 # −1
roman-kashitsyn 24.02.2012 13:14 # 0
SmackMyBitchUp 24.02.2012 13:32 # +1
щас я себя минусану за глупость
roman-kashitsyn 24.02.2012 15:43 # 0
вариант с джавой:
http://ideone.com/ETwvi
(обратим внимание: сообщения печатаются оба раза)
вариант с макросом на clojure:
http://ideone.com/K0quX
(а вот тут сообщения печатаются только второй раз, когда первые два объекта совпадают)
функция на Haskell выглядела бы так: Но вот запихнуть в неё выражения с побочными эффектами скорее всего не получится. Поэтому покажу вот на таком примере: Так вот, выражения someLongCalculation и anotherLongCalculation вычислены не будут.
gegMOPO4 24.02.2012 12:48 # 0
TarasB 24.02.2012 16:33 # +1
gegMOPO4 25.02.2012 09:40 # +1
Говногость 23.02.2012 11:06 # 0
Говногость 23.02.2012 12:22 # 0
Ну я так понял, что просто согласно принципу бритвы Оккама убрали одно понятие. Раньше было так:
«операция »," является точкой следования ->точка следования означает, что все побочные эффекты к моменту операции должны быть закончены->значит всё, что написано до запятой гарантировано выполнится до того, что написано после запятой"
стало:
«операция »," гарантирует, что всё, что написано до запятой гарантировано выполнится до того, что написано после запятой"
меньше понятий, меньше букв.
UncleAli 23.02.2012 12:46 # 0
Что-то мне кажется, что про С++11 можно не думать еще года 2-3: стандарт-то приняли, а как с компиляторами дела обстоят?
Говногость 23.02.2012 13:22 # 0
Точки следования ещё не готовы.
http://gcc.gnu.org/gcc-4.7/cxx0x_status.html
Говногость 23.02.2012 11:18 # +2
j=j++ + a
n=(n=a)+b
По крайней мере только эти выражения фигурируют в примерах.
Сразу бы все проблемы ушли, если бы их (j++ и возможности присваивать результат операции = (присвоения) ) не было.
Проблемы с оптимизацией бы тоже ушли, которые есть из-за этих точек следования, из-за чего в C++11 снова перелопатили стандарт, пытаясь усилить оптимизацию, добавив в стандарт новые сущности и различные исключения из правил.
gegMOPO4 23.02.2012 21:49 # 0
Говногость 23.02.2012 22:19 # 0
Вообще, от постинкремента больше проблем, чем пользы, впрочем как и от любых не чистых функций в правой части выражения.
gegMOPO4 23.02.2012 22:31 # +1
Говногость 23.02.2012 12:11 # 0
Понятно, что порядок конструирования объектов не определён. но допустим уже успел сконструироваться первый объект, а второй после этого сконструированный объект в конструкторе кинет исключение. Понятно, что память занятая под второй сконструированный объект при этом сама освободится. А вот что будет с первым? Тоже освободится сама или утечёт?
UncleAli 23.02.2012 12:43 # +2
Steex 23.02.2012 15:29 # 0
TarasB 23.02.2012 15:58 # +1
TheCalligrapher 23.02.2012 20:24 # −3
Я при этом не говорю, что выражения вида 'i++ || i' надо использовать в коде, но тем не менее иногда что-то подобное бывает весьма полезно.
Говногость 23.02.2012 21:05 # +1
Няшненько... Как же С++/CLI этим раздражает...
gegMOPO4 23.02.2012 21:51 # 0
TheCalligrapher 24.02.2012 00:21 # −2
defecate-plusplus 24.02.2012 09:21 # +1
и оба этих операнда друг на друга не влияют, так что как раз на откуп компилятору отдан порядок их вычисления, как и + и * и т.д.
а для || и && компилятор обязан слева направо вычислять
gegMOPO4 24.02.2012 12:51 # 0
absolut 24.02.2012 13:27 # 0
gegMOPO4 23.02.2012 21:39 # +1
TheCalligrapher 24.02.2012 00:23 # 0
gegMOPO4 24.02.2012 12:49 # 0
gegMOPO4 23.02.2012 21:37 # 0