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

    +7.1

    1. 1
    iInteractionFlagBBS->second->setVisible( (flags & iInteractionFlagBBS->first) ? true : false );

    Тернарный оператор в скобках жгет

    Запостил: guest, 18 Июня 2009

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

    • Анонимус:
      first это указатель?
      Ответить
    • ... где говно?
      Ответить
    • Помоему нормальный код
      Ответить
    • К.О.:
      конструкция
      (flags & iInteractionFlagBBS->first) ? true : false

      легко заменяется на
      flags & iInteractionFlagBBS->first

      так что тернарный оператор тут совершенно излишен. Так-то!
      Ответить
      • setVisible может быть перегружено и принимать аргумент bool и int например.
        В твоем примере "легко заменяется" может привести к вызову setVisible(int) а не setVisible(bool), т.е. совершенно другой функции.

        Хотя это уже можно будет смело назвать говнокодом.
        Ответить
    • 2 К.О.
      ворнинг будет по поводу преобразования к bool.
      скорее всего, этот код именно ворнинг и лечит, так что не говно это никакое, имхо.
      так-то...
      Ответить
    • dmzakh:
      К К.О.

      Я не большой знаток C++, но Ваш код не эквивалентен исходному.

      Исходный код с применением тернарного оператора возвращает логическое значение (true или false).

      Ваш код возвращает результат побитового И, и имеет целый (?) тип с массой возможных значений.

      Вызов
      iInteractionFlagBBS->second->setVisible(...)
      возможно требует булевского значения в качестве параметра.
      Автор скормил методу булевское значение и этим избавился от вероятных предупреждений компилятора о несоответствии типа формального и фактического параметра.
      Такое "лобовое" решение вполне имеет право на существование. Более того, оно весьма наглядное.
      Ответить
    • Код, имхо, хороший образец говна:
      1) незнание приоритетов операторов (побитовое И имеет приоритет много выше тернарного оператора выбора)
      2) результат побитового И, не являясь булевым типом, легко и безо всяких ворнингов приводится к данному типу: 0 - false, не 0 - true.

      Кто-то считает это говном?

      int* a = NULL;
      if (!a) {}
      Ответить
      • Дело в том, что при оптимизации преобразования целых в bool могут генерировать неспособный для логических операций bool. Логические операции над bool, обычно, ожидают 0 или 1 в младшем бите. Наличие единицы в старших битах (после преобразования из целого) на некоторых компиляторах приводит к невозможности правильно выполнять логические операции, хотя в операторе if отрабатывает нормально.
        На пример:
        int i = 10; // mov eax, 10
        bool x = i; // mov [esi - 8], eax
        bool y = false; // mov [esi - 12], 0
        if (x || y)
        // and eax, 1 // обрезаем старшие биты
        // or eax, [esi - 12]
        // jz end_of_the_next_block;
        { /* этот код не выполнится */ }
        хотя сейчас уже не встретить таких компиляторов.
        баги в компиляторе - самое болезненное открытие.
        Ответить
    • 1) а он и должен выполниться раньше, так что про приоритет - это вы, батенька, загнули

      2)
      bool f(bool a) {}
      ...
      f(lags & iInteractionFlagBBS->first);

      ворнинг гарантирован как минимум на vs2005 при неконстантных значениях операндов, возможно с некоторыми исключениями

      3) пример кода с указателем невалиден. поясняю:
      int* a = NULL;
      bool bTrue = !a; // OK, использован оператор not
      bool bFalse = !!a; // OK, прошу заметить два оператора not
      bool bWarning = a; // Warning, нет операторов not - неявное приведение типа
      Ответить
      • #define NULL -1
        Любой код c проверкой на NULL без использования оного NULL - невалиден. Есть, знаете ли, платформы где NULL != 0.
        Ответить
    • Так говнокод или нет ?
      В плюсах не силен, но разве там нет приведения типа, которым можно заменить это тернарное безобразие ?
      Ответить
    • #9,
      учитывая, что
      typedef enum
      {
      false,
      true
      } bool;

      то грубо говоря bool - это int, и скормить функции можно любое значение из диапазона.
      Другое дело, что в самой функции скорее всего будет проверка в виде
      if (param)
      {
      //...
      }
      else
      {
      //...
      }

      и тернарный оператор будет излишен
      Ответить
    • А так?
      (flags & iInteractionFlagBBS->first) != 0
      Ответить
    • Great:
      Капитан, кажется, потерял былое знание плюсов. (

      Конструкция x не эквивалентна конструкции (x ? true : false) или (x == true) или (x != false)

      Никаким другим образом преобразовать значение к bool нельзя
      Ответить
    • !!(flags & iInteractionFlagBBS->first)
      я так пишу в подобных случаях
      Ответить

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