Кресты / Говнокод #21629 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
/* public static */ bool
TestFooFactory::checkItem(const Foo& item)
{
  if (!&item)
    return false;
  return true;
}

null-ccылки в C++? Легко!

Запостил: Elvenfighter Elvenfighter, (Updated )

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

  • ну, если какой-то чудило изхитрился передаватьв функцию, принимающую ссылку, разыменованный nullptr, то только так и воевать.
    Ответить
    • Ну в том-то и задумка. Только вот само по себе разыменование nullptr -- это UB.
      Ответить
    • Запросто. Предположим человек работает у себя в коде с указателями, есть возможность получить нулевой указатель, а его коллега написал ему фраймверк который на входе принимает ссылки, ну человек бесхитросно возьмет код коллеги на напишет SuperDuperFramework::function(*pointer) - и весь балет.
      Ответить
      • Проблема в том, что любой адекватный компилятор этот код превратит в return true. И гцц и шланг это делают.

        В итоге вся эта петушня бесполезна. Проверять угазатель на null нужно до разыменования.
        Ответить
      • я понимаю, как работает механизм "ой я тут накодил, нужен памперс"
        Ответить
    • Пример: в реальном режиме 8086 nullptr — это то место, где хранится указатель на обработчик нулевого прерывания; разыменованный nullptr — это собственно указатель на обработчик нулевого прерывания (INT 0, вызывается при попытке деления на ноль). Для того, чтобы повесить свой обработчик с возможностью возврата к оригинальному, нужно где-то сохранить адрес оригинального обработчика. Чтобы сохранить адрес оригинального обработчика, вызываемого при попытке деления на ноль, нужно... разыменовать nullptr ну или сделать memmove/memcpy, но это совсем для слабаков.
      Ответить
    • Ваще-то можно ... была у меня динамическая либа, из которой хотелось вызвать функцию, но принимала она ссылку на собственный класс внутри (чужая либа, без хидеров).
      Сделал хидер себе вроде такого
      checkItem(const Foo* item)
      Так я уже могу вызвать эту функцию из своего кода на ++.
      Оставалась проблемка создать объект Foo ... слава яйцам, конструктор Foo там тоже экспортирован был, тупо распределял на вскидку большой кусок памяти и отдавал его конструктору из либы.

      Но вопщем-то да, ссылка - это синтаксический сахар, на самом деле там указатель.
      Ответить
      • Я правильно понимаю, что в этой твоей библиотеке функция принимала ссылку, а ты не такой как все и решил сделать ей параметр указателем? Зачем? И как так получилось, что имена совпали? Они там свои функции помечали extern C?
        Ответить
    • Я в Objc часто так пишу. Правда там не this, а self.
      Знаешь зачем?
      Ответить
      • Не знаю, зачем ты это делаешь в обжси, а в плюсах вызывать метод с невалидным this запрещено. Хотя я раньше так писал, потому что молодой был)))
        Ответить
        • В ObjC создание объекта занимает 2 шага
          1) alloc (выделение памти
          2) init (конструктор, инициализация внутреннего состояния)

          В случае ошибки тебе вернут nil. Например, если не удалось сделать alloc или init.

          Так вот вызов родительского init возвращает тебе self.
          Его нужно проверить на nil, потому что если он nil то нет смысла вызывать свой конструктор: ошибка в родителе.

          Потому в Objc можно встреить такой код
          - (id)init
          {
              self = [super init];
              if (self)
              {
                  petuhField = @"kuroshka";
              }
              return self;
          }
          Ответить
          • В крестах объект создаётся тоже в два шага, но там такой хуйни нет.
            Ответить
            • В крестах можно хотя-бы конструктор вызвать не вызываю вручную alloc)
              Ответить
            • Да, намешали говно с мочой (аллокацию и инициализацию). А вот то, что конструктор может что-то возвращать - это заебись. В плюсах вот без исключений никак.
              Ответить
              • Не суди строго. Это было начало 80х.
                Зато можно аллоцировать на разных аллокаторах в независимости от конструктора) Ну точнее раньше так было.

                Конструктор может вернуть или nil или объект.
                Ответить
                • > Не суди строго. Это было начало 80х.
                  Мой первый язык, не судите строго плиз.
                  Ответить
              • да ладно? new (std::nothrow) MyClass(args...); вернет 0 если не хватило памяти на выделение.
                Ответить
      • в плюсах эта проверка не имеет смысла, а знаешь почему?
        Ответить
          • раньше это было UB. Сейчас по стандарту проверка this против nullptr не имеет смысла и компиляторы спокойно могут её выкидывать
            Ответить
            • То есть компиляторы предполагают, что this не может быть нулём?
              Ответить
                • > раньше это было UB
                  Ты меня запутал >_< Если раньше это было уб, то проверка и тогда не имела смысла "по стандарту".
                  Ответить
                  • это неправильно. Не только с точки зрения паттернов и канонов, но также с точки зрения базовой логики, "я мыслю, и значит я существую": сомневаться в собственном существовании глупо. Не удалось создать экземпляр? - ну так обработай такой сценарий по месту неудачного создания.
                    Ответить
                  • Если точнее, то this это выражение, возвращающее prvalue. В this = nullptr столько же смысла, как и в 1 = 0.
                    Ответить
                    • вроде как в какой-то ранней итерации (типа си с классами) this можно было менять. Потом это (praise the sun) убрали
                      Ответить
                      • > this можно было менять
                        Ну это же ахуенно! Можно прямо из метода переаллоцироваться и пофиксить указатель на себя в вызывающем коде.
                        Ответить
                        • Пофиксил указатель на твоём анусе, проверь.
                          Ответить
                        • я хз, менялся ли указатель в вызывающем коде (подозреваю что нет), но суть проблемы очевидна: после самостоятельного "телепорта" все указатели извне инвалидируются и потом эту нечисть не убьешь
                          Ответить
  • Острологи объявили неделю разыменования нулевых указателей.
    Ответить

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

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8