1. C++ / Говнокод #23498

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    // https://github.com/telegramdesktop/tdesktop/blob/5f5770dd46491133b135a71fc2d4f92d13107ade/Telegram/SourceFiles/history.cpp#L1455
    
    int History::countUnread(MsgId upTo) {
    	int result = 0;
    	for (auto i = blocks.cend(), e = blocks.cbegin(); i != e;) {
    		--i;
    		for (auto j = (*i)->items.cend(), en = (*i)->items.cbegin(); j != en;) {
    			--j;
    			if ((*j)->id > 0 && (*j)->id <= upTo) {
    				break;
    			} else if (!(*j)->out() && (*j)->unread() && (*j)->id > upTo) {
    				++result;
    			}
    		}
    	}
    	return result;
    }
    
    void History::updateShowFrom() {
    	if (showFrom) return;
    
    	for (auto i = blocks.cend(); i != blocks.cbegin();) {
    		--i;
    		for (auto j = (*i)->items.cend(); j != (*i)->items.cbegin();) {
    			--j;
    			if ((*j)->id > 0 && (!(*j)->out() || !showFrom)) {
    				if ((*j)->id >= inboxReadBefore) {
    					showFrom = *j;
    				} else {
    					return;
    				}
    			}
    		}
    	}
    }

    очередная порция говнеца из телесрамного клиента

    Запостил: j123123, 07 Ноября 2017

    Комментарии (64) RSS

    • if (unreadCount()) {
      	if (!isEmpty()) {
      		return (loadedAtTop() || minMsgId() <= inboxReadBefore) && (loadedAtBottom() || maxMsgId() >= inboxReadBefore);
      	}
      	return false;
      }
      Ответить
      • for (auto i = pending.begin(); i != pending.end();) {
        	if ((*i)->history() == this) {
        		i = pending.erase(i);
        	} else {
        		++i;
        	}
        }

        Нахуя такие циклы делать?
        Ответить
        • На кой хер писать цикл for, если внутри for () выражения нихрена не меняется переменная i, а меняется некое говно в else внутри тела этого говноцикла?
          Ответить
          • не хватает огурц статического анализатора
            PVS Studio, CLion, ReSharper for C++... :)
            Ответить
          • Да хуй с ним, с циклом... Функции из топика вообще триггерят UB, если blocks пустой или в каком-то блоке нету ни одного item'а. Но суровые Цари Олимпа, само собой, способны удержать все инварианты программы в голове, поэтому assert'ы и проверки им нинужны.
            Ответить
            • Я вообще не понимаю как VK работает. Как можно поддерживать 4 тысячи строк кода на си с переменными типа i и j.

              Но может быть я просто не умею в олимпиаду
              Ответить
              • > с переменными типа i и j
                Чем бы дитя не тешилось, лишь бы поля в объектах не называло в духе m.mpx[3].dpx.dx... А i и j в небольших функциях - вполне терпимо.
                Ответить
                • ну так-то я понимаю что i и j это цикл и вложенный в него другой цикл, да
                  Ответить
            • Можешь пояснить, где уб?
              Ответить
              • В декременте end() у пустой коллекции. А тьфу, он же тогда равен begin() и цикл не начнётся. Значит всё ок.
                Ответить
                • Там этого нет. Цикл сделает ноль итераций для пустой коллекции.
                  Ответить
    • void History::clear(bool leaveItems) {
      	if (unreadBar) {
      		unreadBar = nullptr;
      	}
      	if (showFrom) {
      		showFrom = nullptr;
      	}
      	if (lastSentMsg) {
      		lastSentMsg = nullptr;
      	}

      О да, давайте сначала проверим, равно ли некоторое говно nullptr, и вот если не равно, то тогда присвоим nullptr, а если и так равно, то и присваивать не надо, ОПТИМИЗАЦИЯ
      Ответить
      • олимпиаднички, сэр

        ну может быть оно автогенерённое?
        Ответить
      • Может это привычка от конструкций типа
        if (socket_ptr) socket_ptr->close();

        Когда хуяришь быстро-быстро много строк говна, думать над мелочами особо некогда. Только привычки и остаются.
        Ответить
    • А че такого? Я все время так пишу. По сравнению с проектами в моем отделе выглядит неплохо даже. Скажи спасибо, что эти функции не по 2к строк.
      Ответить
    • > History::countUnread(MsgId upTo)

      Где const?

      > auto i = blocks.cend()
      не осилили reverse_iterator ?

      > (*j)->id <= upTo

      Как так, олимпиадники упустили возможность применить бинарный поиск?
      Ответить
      • > Где const?
        А вдруг у итерации по blocks есть побочные эффекты (типа подкачки с флешки/сервера)?
        Ответить
    • Посмотрел повнимательнее и совсем недоумеваю, че ты гонишь. Нормальный код. Разве что rbegin/rend стоило использовать.
      Ответить
      • Ну вот допустим эта хрень
        for (auto i = blocks.cend(), e = blocks.cbegin(); i != e;) {
        	--i;

        Нахрена делать такой for() ? В цикле в for () обычно что-то уменьшают-увеличивают, ну типа:
        for (int i = 14; i >= 0; i--)

        Тут же этот i уменьшается не в for(тут) а в самом теле цикла. Зачем? Зачем делать for в котором нихрена не меняется внутри круглых скобок?
        Ответить
        • потому что end разыменовывать нельзя, а про reverse_iterator они не знают

          > for (int i = 14; i >= 0; i--)

          а теперь замени int на uint, раз всё так просто
          Ответить
          • > потому что end разыменовывать нельзя, а про reverse_iterator они не знают

            А что им мешало сделать например так:
            for(auto i = blocks.cend() - 1
            Ответить
            • UB на пустом контейнере. Да и на контейнере с одним элементом тогда первый элемент проебёшь (т.к. blocks.cend() - 1 будет равен blocks.cbegin()).
              Ответить
              • Ну ничего, можно перед циклом втулить
                if( blocks.cend() != blocks.cbegin() )
                Ответить
              • > Да и на контейнере с одним элементом тогда первый элемент проебёшь (т.к. blocks.cend() - 1 будет равен blocks.cbegin()).

                вообще да, если уж не знать про reverse_iterator, правильнее будет какой-нибудь while использовать
                auto i = blocks.cend(), e = blocks.cbegin();
                while(i != e)
                {
                  --i;
                  ...
                }


                Когда я вижу for(), я ожидаю что в круглых скобочках этого for() будет происходить некая хрень, меняющая то, из-за чего условие в for() должно перестать работать
                Ответить
                • > правильнее будет какой-нибудь while использовать
                  И у тебя i и e вывалятся наружу, а с for'ом они были локальными для тела цикла...

                  З.Ы. Хотя фишка из нового стандарта вроде позволит написать как-то так:
                  while (auto i = blocks.cend(), e = blocks.cbegin(); i != e)
                  {
                    --i;
                    ...
                  }
                  Ответить
                  • З.Ы. Не, не позволит. Они эту штуку только для if'а прикрутили, а для while не стали, т.к. уже есть for.
                    Ответить
                    • Крестовики пол часа обсуждали как итерироваться
                      Ответить
                      • А рубистов только на 7 сообщений хватило: http://govnokod.ru/23469
                        Ответить
                        • а я
                          а у нас
                          а мы
                          items = %i[matz katz oops]
                          
                          
                          #  для функциональщиков
                          items.each {|name| p name}
                          
                          #  для педантов
                          for name in items
                            p name
                          end
                          
                          # для любителей многострочных лямбд
                          items.each do |name|
                            p name
                          end
                          
                          
                          # для скучных
                          for i in (0...items.size)
                            p items[i]
                          end
                          
                          ########
                          # Магия
                          class Symbol
                            def print_me
                              p self
                            end
                          end
                          
                          # теперь можно так
                          items.each(&:print_me)
                          Ответить
                          • А в крестах можно по-сишному через индексы, по-крестовому через итераторы, по-новокрестовому через for-по-контейнеру, через вореции предыдущих джвух с auto, по-функциональному через алгоритмы (с внешней функцией, классом-со-скобочками или лямбдой). А ещё можно поюзать while или даже пойти против системы и взяться за goto...

                            В общем, скучно в этом вашем ruby.
                            Ответить
                            • >>через индексы
                              cм "для скучных"

                              >>по-крестовому через итераторы, п
                              # для любителей явных итераторов
                              enum = items.enum_for
                              loop do
                                p enum.next
                              end
                              
                              # для еще более любителей явных итераторов
                              enum = items.enum_for
                              while true
                                begin
                                p enum.next
                                rescue StopIteration
                                  break
                                end
                              end


                              >>через for-по-контейнеру,
                              см "для педантов"

                              >>по-функциональному через алгоритмы
                              ну там сверху три примерчика же

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

                                Да и лямбду описать у вас всего жалкая пара способов.

                                А где аналог варианта с goto?

                                Нету в вашем руби простора для самовыражения.
                                Ответить
                                • >>Да и лямбду описать у вас всего жалкая пара способов.
                                  Обижаешь! Это же руби, тут всего по четыре способа
                                  # четыре лямбы Маца
                                  
                                  la = proc {|x| p x}
                                  la2 = lambda {|x| p x}
                                  la3 = -> (x) {p x}
                                  la4 = Proc.new do |x|
                                    p x
                                  end



                                  >>А где аналог варианта с goto?
                                  Держись за стул: https://rubygems.org/gems/goto
                                  Category: Library/Evil
                                  Ответить
                                  • Фи, какие-то однообразные у вас лямбды... То ли дело в крестах:
                                    - указатель на функцию, как в няшной
                                    - функторы аля класс-с-оператором-скобки
                                    - каррирование и кобенирование через bind
                                    - бустовая магия _1 < _2
                                    - настоящие лямбды из нового стандарта

                                    Каждый способ по-своему уникален.
                                    Ответить
                                    • хехе, карирование (всмысле создание функции по другой функции с замороженными аргументами) у нас в питончике е
                                      Ответить
                            • по-сишному через указатели
                              Ответить
                              • Давайте считать это алиасом для " по-сишному через индексы"
                                Ответить
                                • Давайте не будем? Т.к. это предок итераторов (обход linked list через for(node*p =begin; p; p=p->next), к примеру).
                                  Ответить
                                  • >> for(node*p =begin; p; p=p->next)
                                    индексация +1 за пределом области памяти вернет NULL, или туда надо явно положить NULL?

                                    Предок-то он может и предок, то физически ведь получается тоже самое
                                    адрес начала массива (указатель) плюс сдвиг размером с тип данных, умножить на индекс
                                    Ответить
                                    • Какого ещё массива? У связного списка ноды могут быть раскиданы по всей куче...

                                      Совсем люди позабыли об основах со своими языками высокого уровня...
                                      Ответить
                                      • блин, если ты именно о связанном списке то да. Ну я тоже могу сделать объект, указывающий на следующий объект и реализовать в нем Enumerable. даже проще могу
                                        Ответить
                                        • Не реализовать в нём Enumerable, а обходить по хардкору, читая поле напрямую: foo.@next.
                                          Ответить
                                          • да ради бога
                                            class Node
                                              attr_reader :next_node, :name
                                            
                                            
                                              def initialize(name, next_node = nil)
                                                @name = name
                                                @next_node = next_node
                                              end
                                            end
                                            
                                            list = Node.new 'A', Node.new('B', Node.new('C'))
                                            
                                            
                                            $node = list
                                            # гыгыггыгы
                                            begin
                                              p $node.name
                                            end while $node ? $node = $node.next_node : false


                                            правда за такое уже пиздят, конечно.

                                            И RubyMine и RuboCop верещат на такой код
                                            Ответить
                            • > и взяться за goto...

                              http://govnokod.ru/19105 можно даже с goto без if
                              Ответить
                  • >И у тебя i и e вывалятся наружу, а с for'ом они были локальными для тела цикла...

                    Можно еще сверху все обернуть фигурными скобками, чтоб не ВЫВАЛИВАЛОСЬ
                    Ответить
                    • в новой серии программы "j123123 и обфускация простого кода" мы расскажем вам о том, как на ровном месте получить третий уровень вложенности вместо первого.
                      Ответить
                      • Это все потому, что в C++ нельзя доопределить новый вид цикла for (назовем его for_2 ), в котором чтоб for_2( int a = 0; a < 10; вотэтахрень) выполнялась каждый раз не после тела цикла, а перед телом цикла
                        Ответить
                        • вообще, все эти for и while со всякими там break, continue и проч. лучше б чтоб были макросней какой-нибудь, которая бы раскрывалась в питушню из goto с if-ами. Ну и по аналогии чтоб можно было свои циклы придумывать
                          Ответить
                        • зачем? В с++ можно сделать for (auto &val : reversed(cont)) { ... }, который тут и требуется
                          Ответить
                          • Да, это еще в С++11 такую хуиту добавили. Range-based for loop называется. Ну т.е. в сам компилятор для этого впиливают некую хрень. Нет чтоб сделать сам язык синтаксически расширяемым, чтобы сам программист (не только разраб компилятора) мог добавлять всякие там новые циклы через какие-то макросы, и чтоб все стандартные циклы были через те же самые макросы в такой же способ реализованы
                            Ответить
                            • я говорил именно про ф-ю reversed. Критикуешь с++ за метушню, но предлагаешь язык, еще более метушиный, чем с++. Клин клином?
                              Ответить
                              • Крестометушня это захардкоженное в крестокомпилятор говно, я же предлагаю универсальную метушню, для которой сам компилятор перепиливать под каждый новый говностандарт не нужно, а нужно лишь сделать особую компилтайм говнокодогенерацию, умеющую с кодом как с данными работать и делать вообще любую поеботу. И для новой поебени из нового говностандарта будет достаточно лишь подключить новую компилтайм-либу, которая какое-то там говно переписывает в другое говно в компилтайме на уровне AST
                                Ответить
                                • Вам уже пора этот язык мечты написать. Только пусть он в C++ (Java/C#/PHP - не важно, главное - в популярный язык) компилируется, будет его надмножеством (или надмножеством его разумного подмножества), но библиотеки пусть останутся существующие и синтаксис не будет кардинально новым (а то у нас сука каждый первый уже создал свой язык с новыми синтаксисом и стандартной библиотекой, требующий анальной боли при прикручивании библиотек, написанных для предыдущих языков; когда уже у программистов погорят языки и библиотеки, чтоб пожарные шланги модулей наконец унифицировали?)
                                  Ответить
                                  • > Только пусть он в C++ (Java/C#/PHP - не важно, главное - в популярный язык) компилируется

                                    Пусть только "Java/C#/PHP - не важно, главное - популярный язык" сначала компилироваться начнет

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

                                    Специально для тебя могут унифицировать охлажденные дилдаки.
                                    Ответить
                                    • > Пусть только "Java/C#/PHP - не важно, главное - популярный язык" сначала компилироваться начнет
                                      Java/C# не просто компилируемые, а дважды компилируемые. Разве этого мало?

                                      > Специально для тебя могут унифицировать охлажденные дилдаки.
                                      Что за питушню я читаю?
                                      Открою страшную правду тем, кто долго сидел в интернетах, что пожарный шланг - это часть оборудования для тушения огня, а не термин с порносайта.

                                      Ситуация в Интернете стала напоминать время, когда в начале XX века в США пожарные шланги в каждом городе были сделаны по-своему. Это приводил к тому, что пожарные из соседнего города не могли помочь в случае серьёзного пожара.
                                      В. Соломенчук. Понятный самоучитель Интернет. Питер, 2008. с. 188
                                      Ответить
                                      • # пожарные шланги в каждом городе были сделаны по-своему

                                        Как вообще так можно было сделать?
                                        Ответить
                                        • > Как вообще так можно было сделать?
                                          Время было другое, наверно не продумали всё.
                                          Вон у нас до сих пор наличными расплачиваются, а люди будущего будут удивляться, как же не лень было нам считать сраные копейки и пердолиться со сдачей, когда достаточно было получать всё нужное сразу в холодильник или просто взять из магазина нужный товар и пойти домой, максимум - дедовским способом поднести телефон к терминалу у бабушки на улице.
                                          Ответить
                        • Почему это нельзя?
                          #define for_2(A, B, C) for (A; C, B;)

                          Ответить
                    • Не просто скобками, а do{ ... }while(0).
                      Ответить
      • И да, вот можно две эти хуйни сравнить
        for (auto i = blocks.cend(), e = blocks.cbegin(); i != e;) {

        и
        for (auto i = blocks.cend(); i != blocks.cbegin();) {

        В первом случае делается переменная e, которой присваиваем blocks.cbegin(), во втором же никакой переменной e не создается. Почему и там и там не сделать каким-нибудь одним способом? Например, если получение blocks.cbegin() это какая-то там операция, которая не может быть соптимизирована (т.е. если компилятор не может доказать, что cbegin на каждой итерации данного сраного цикла будет все тем же) то и там и там сделайте e = blocks.cbegin() хуйню
        Ответить
    • говно потому что алгоритмы не используются. Очередное г из разряда "надо полностью читать и держать в голове чтобы понять что оно делает"
      Ответить

    Добавить комментарий