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

    +57

    1. 1
    if (!this) return;

    Запостил: Actine, 05 Сентября 2014

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

    • А вдруг это защита от тех, кто попытается метод класса вызвать как обычную функцию?
      Ответить
      • Скорее защита (негарантированная) от вызова по нулевому указателю: http://ideone.com/ULGhTK
        Ответить
        • Для невиртуальных методов она вполне гарантированная.
          Ответить
          • А как насчёт оптимизаций, которые вполне могут решить что нулевым this быть не может и убрать соответствующие ветвления?

            http://blogs.msdn.com/b/oldnewthing/archive/2014/06/27/10537746.aspx
            Ответить
            • Дык разадресации до этого if'а нет. foo->bar(a, b) по идее не считается т.к. просто вызывает mangled_bar(foo, a, b).
              Ответить
              • Метод не может быть вызван так чтобы в this оказался 0 и не породить UB при этом (по стандарту вызом метода по невалидному указателю UB вне зависимости от того что этот метод использует). Компилятор справедливо решает что программист не идиот и UB не допустит и оптимизирует код на основании этого вывода. Если UB всё же наступает компилятор прикрывается Стандартом, по которому ему разрешено всё в этом случае. По моей ссылке подобные оптимизации разбираются. Также там есть ссылка на блог разработчиков шланга, которые тоже описывают подобное.
                Ответить
          • Разве вызов метода класса по нулевому указателю - не UB? Любого метода?
            Ответить
            • Вроде бы UB, равно как и вызов по любому другому указателю, не указывающему на объект правильного типа. Но в стандарте что-то не могу найти строчку.
              Ответить
              • 5.2.5/2
                ... The expression E1->E2 is converted to the equivalent form (*(E1)).E2;...
                т.е. разыменование нуля - UB
                Ответить
                • это для полей, а не методов
                  что там для метода разыменовывать?
                  Ответить
                  • а метод что уже не член? читай дальше, п.4 например:
                    ... If E2 is a (possibly overloaded) member function...
                    Ответить
                    • метод это не член, он (и данные, на него указывающие) не хранится в экземпляре
                      если только он не виртуальный
                      Ответить
                      • Виртуальный, тащемта, тоже не хранится в экземпляре. Он же по реализации ничем не отличается от обычного. Только вызывается по другой схеме.
                        Ответить
                        • Бля, я для кого в скобках примечание сделал? Я думал, я себя защитил от буквоедов. Но от слепых буквоедов защиты нет.
                          Ответить
                          • Ты мыслишь с точки зрения возможной реализации, а я тебе про Стандарт говорю.
                            Ответить
                            • Тарас вроде ясно сказал что метод, то есть управляющий данными код, - non penis canina.
                              Ответить
                            • Ох ты ж крестопиздоблядский Сиплюструп. Оказывается в крестах вовсе нет методов! Только то что называется member function.
                              Плюс эта функция может быть статичной, а может и не быть.

                              If E2 is a (possibly overloaded) member function, function overload resolution (13.3) is used to determine whether E1.E2 refers to a static or a non-static member function.
                              If it refers to a static member function and the type of E2 is “function of parameter-type-list returning T”, then E1.E2 is an lvalue; the expression designates the static member function. The type of E1.E2 is the same type as that of E2, namely “function of parameter-type-list returning T”.
                              Otherwise, if E1.E2 refers to a non-static member function and the type of E2 is “function of parameter-type-list cv ref-qualifieropt returning T”, then E1.E2 is a prvalue. The expression designates a non-static member function. The expression can be used only as the left-hand operand of a member function call (9.3). [ Note: Any redundant set of parentheses surrounding the expression is ignored (5.1). — end note ] The type of E1.E2 is “function of parameter-type-list cv returning T”.

                              Экая гомосятина ваши кресты. С ума можно сойти.
                              Ответить
                            • Невозможно реализация, в которой объект не хранит данные, прямо или косвенно указывающие на то, как вызывать нужный виртуальный метод. Иначе получится компутер-телепат.
                              Ответить
        • прям паттерн Special Case без наследования
          Ответить
    • [:\\||//:] - gk #11357
      Отлично помню, какое это произвело на меня впечатление. Будто глаза открылись на C++.
      Ответить
      • А мне http://govnokod.ru/11251 вспомнился.
        Там всего 4 буквы. А мог ведь срач и на 100+ постов разгореться при нужной фазе луны и достаточном числе желающих поспорить.

        Кстати та крестоконструкция и сейчас меня приводит в некий ступор.
        Ответить
        • О, а я сам делал так же, как в том треде:
          //very_big_struct s; // before
          very_big_struct & s = *new very_big_struct; // after
          Структура выделялась на стеке и жила весь жизненный цикл программы, а стека было очень мало - 32 килобайта, что ли? Сигсегв, короче, в некоторых местах вылезал.
          А таким образом оказалось проще всего поправить все места, где есть обращения к структуре; точнее, не поправлять их вообще.
          Ответить
        • Да хули: http://govnokod.ru/14093
          Ответить
        • А мне ещё вот этот понравился: http://govnokod.ru/13410

          Особенно код Борманда.
          Ответить
    • Хотфикс NULL pointer exception. Вообще на валидность проверять до вызова надо, хотя по моему это вообще потребность что не должна возникать.
      Пэ.Сэ. Особо нежный ароматъ сему говну придастъ если функцъия азъ виртуальна будетъ.
      Ответить

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