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

0

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

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

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

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

  • К.О.:
    конструкция
    (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
    {
    //...
    }

    и тернарный оператор будет излишен
    Ответить
  • Great:
    Капитан, кажется, потерял былое знание плюсов. (

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

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

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

Из-за тебя ушел bormand, guest!

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


    8