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

    0

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    template <typename T>
    int h1(const T& t){
       if (t < 1){
           return 0;
       } else if (t >= 1){
           return 1;
       }
    }

    Всегда-ли тут есть return?

    Запостил: SemaReal, 29 Сентября 2017

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

    • свинособаки, это пост для привлечения вашего внимания
      Ответить
    • bool T::operator< (int) const { return false; }
      bool T::operator>= (int) const { return false; }
      Ответить
    • T = double
      t = NaN
      Ответить
      • Ну ты как не крестоблядь.
        Ответить
      • UB же
        Только в вореанте с throw нету UB
        Ответить
        • а где там у госта UB?

          ЗЫ и сравнение с наном тоже не ёбы:
          https://stackoverflow.com/a/1573715/360695
          и кто бы мог подумать...
          Ответить
          • UB в том, что функция ничего не возвращает в этих случаях. По факту может вернуть последнюю какашку со стека.
            Ответить
            • > UB в том, что функция ничего не возвращает в этих случаях.

              это было с самого начала очевидно.

              в случае перегруженого оператора сравнения, теоретически компилер должен видеть (== варнинг) что есть одна ветка которая ничего не возвращает - потому что компилер будет видеть if()ы с вызовами методов.
              Ответить
          • реально отличный способ эмулировать isnan(): проверять что !(foo == foo)

            прыщеблядство какое
            Ответить
            • получается сортировка массива где есть NaN может попросту наебнуться?
              Ответить
              • https://ideone.com/OUK3k6
                Знатоки Стандарта, отзовитесь: nan в sort - UB или не UB?
                Ответить
                • Крестопроблемы! Вот JS всё предусмотрено:
                  [1, 2, NaN].sort() // [1, 2, NaN]
                  [2, 1, NaN].sort() // [1, 2, NaN]
                  [1, NaN, 2].sort() // [1, 2, NaN]
                  [2, NaN, 1].sort() // [1, 2, NaN]
                  [NaN, 1, 2].sort() // [1, 2, NaN]
                  [NaN, 2, 1].sort() // [1, 2, NaN]
                  [1, 2, 10].sort() // [1, 10, 2]
                  Ответить
                  • [1, Infinity, -Infinity, NaN].sort() // [-Infinity, 1, Infinity, NaN]
                    Ответить
                  • replace(NaN, 0) тоже
                    Ответить
                    • И сколько вореантов это сделать!
                      xs => ''.replace.call(xs, /NaN/g, 0).split(',').map(Number)
                      xs => Function((`return [${xs}]`).replace(/NaN/g, 0))() // the best
                      xs => xs.map(x => +''.replace.call(x, NaN, 0))
                      Ответить
                • какое ж это undefined behavior, если поведение определено? Сортировка завязана на сравнении через оператор <. В с++ стандарте ссылка на IEEE 754 floating point representation. А он в свою очередь диктует, что операторы сравнения с nan должны возвращать false кроме !=, который должен возвращать true.

                  По факту, эл-ты не будут переставляться с nan. А дальше уже зависит от алгоритма сравнения. Стандарт не определяет какой именно алгоритм должен использоваться для сортировки (лишь его максимальную вычислительную сложность), соответственно, поведение сортировки с nan implementation-defined.
                  Ответить
                  • И правда. Почитал 14-й Стандарт, обнаружил вот такие требования к входным данным sort'а:
                    (25.4.1.1, 2):
                    Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2).
                    The type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable
                    (Table 22).


                    Насчёт Compare от бедных программистов требуется вот это:
                    (25.4, 3):
                    For algorithms other than those described in 25.4.3 to work
                    correctly, comp has to induce a strict weak ordering on the values.


                    (25.4, 4):
                    The term strict refers to the requirement of an irreflexive relation (!comp(x, x) for all x), and
                    the term weak to requirements that are not as strong as those for a total ordering, but stronger than
                    those for a partial ordering. If we define equiv(a, b) as !comp(a, b) && !comp(b, a), then the
                    requirements are that comp and equiv both be transitive relations [...]


                    Несложно видеть, что operator< для double — вполне себе транзитивное отношение даже с учётом nan. Таким образом, сортировка double по Стандарту корректна всегда. Далее можно посмотреть на описание sort'а:
                    (25.4.1.1, 1):
                    Effects: Sorts the elements in the range [first,last).


                    Ну и наконец:
                    (25.4, 5):
                    A sequence is sorted with respect to a comparator comp if for every iterator i pointing to
                    the sequence and every non-negative integer n such that i + n is a valid iterator pointing to
                    an element of the sequence, comp(*(i + n), *i) == false.


                    Таким образом (исходя из «for every iterator i»), Стандарт гарантирует, что любой массив double'ов будет отсортирован так, что если выкинуть из результата сортировки nan'ы — результат останется отсортированным. А положение nan'ов действительно ID, поскольку comp(nan, *i) == false.
                    Ответить
                    • А, вот я и обосрался:
                      equiv(1.0, nan) == true
                      equiv(nan, 2.0) == true
                      equiv(1.0, 2.0) == false

                      Так что всё получается не так однозначно ...
                      Ответить
                    • Ага, хуй
                      https://ideone.com/cPpoUh

                      Потому что нельзя отсортировать массив, если элементы несравнимые. Или хз как это свойство называется, короче 1 !< nan, nan !< 2, но 1 < 2
                      Ответить
                      • А вот для мержсорт, кажется, корректно должен отрабатывать.
                        Ответить
                        • Нет. Мерж [nan, 1, 2] и [4, 5, 6] может вернуть [4,5,6,nan,1,2], т.к. (nan < 4) == false.
                          Ответить
                      • Угу, выше написал — equiv(a, b), определённое как !comp(a, b) && !comp(b, a), должно быть транзитивно, а nan'ы эту транзитивность нарушают.
                        Ответить
    • Clang -- норм: https://wandbox.org/permlink/168d7ugpLITA36HS
      warning: control may reach end of non-void function [-Wreturn-type]
      Illegal Instruction

      GCC -- тоже:https://wandbox.org/permlink/B5u3w8idWSPgMr97
      warning: control reaches end of non-void function [-Wreturn-type]
      0


      Как там ваши корпоративные* компиляторы?

      Шо таки такое это "Illegal Instruction"?
      Ответить
      • > Шо таки такое это "Illegal Instruction"?
        Мне кажеться, шланг честно не стал генерировать код для возврата из функции после if'а.
        Ответить
        • Нет, все не так. https://godbolt.org/g/Z5EVAE

          > ud2
          > UD2: Undefined Instruction
          > Generates an invalid opcode.
          Ответить
      • вывод: компильте с -Werror
        Ответить

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