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

    +24

    1. 1
    2. 2
    3. 3
    Fixed f = 0.2;
    	f = std::abs(f);
    	std::cout << (float)f;

    Угадайте, чему будет равно f?
    Fixed - тип из той же библиотеки, что и в http://govnokod.ru/11294

    Запостил: TarasB, 10 Июля 2012

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

    • Ближайщая двоичная дробь, укладывающаяся в границы float, не?
      Ответить
    • тревожный стук барабанов
      зрители замерли, завороженно глядя на неравную борьбу маленького героя, несущего свет, с огнедышащим крестоблядским чудовищем из преисподней
      кто победит в этом кровопролитном поединке?
      что вернет std::abs от исчадия ада?
      верно ли, что бесстрашие граничит с безумием?
      Ответить
    • А вы скачайте библиотеку ну или скопируйте её фрагмент и проверьте
      Ответить
      • test.cxx: In function 'int main()':
        test.cxx:186:16: error: call of overloaded 'abs(Fixed&)' is ambiguous
        Ответить
        • В 2003й студии проверяй
          Ответить
          • И при полной Луне.
            Ответить
          • [rat4@notebook ~]$ uname -o
            GNU/Linux
            Ответить
            • Короче у меня ноль выдаёт, потому что неявно приводится к int @_@
              Ответить
              • std::abs vs std::fabs

                ты ведь доволен выбором инструмента (окаменелое говно мамонта 2003 года), который из перегрузок abs(integer type) и abs(float type) выбрал не то, что ты хотел?
                Ответить
                • > выбрал не то, что ты хотел
                  И еще и ничего об этом не сказал
                  Ответить
                  • да я вообще подозреваю, что в 2003 студии cmath тупо помещает сишные abs(int) и fabs(double) в namespace std { using ::abs; using ::fabs; } и больше ничего не делает
                    от микрософта можно ожидать чего угодно

                    стандарт то в 2003 году допилили окончательно, наивно полагать, что в 2003 студии (7.1) четкая его поддержка (это же по сути багфикс 2002й .net студии - 7.0)

                    у меня на работе вообще переход с 6.0 в свое время был сделан сразу на 2005 (8.0), а 7.0/7.1 я видел только в институте

                    но Тарас лёгких путей не ищет, нашёл левую говнобиблиотеку, взял студию, которая на его селероне хоть как то ворочается, а в итоге виноваты крестобляди
                    Ответить
                    • Кстати в то время MS никак не мог успокоиться со скопом переменных в for... 2005я студия - первая, в которой for работает так, как положено, а не так, как взбрело в голову левой пятке авторов.

                      В 2003 студии, если не ошибаюсь, нельзя писать так:
                      for (int i=0; i<10; i++) { /* ... */ }
                      for (int i=0; i<10; i++) { /* ... */ }

                      P.S. Тарас, попробуй закомпилить этот код, пожалуйста, раз уж компилятор под рукой.
                      Ответить
                      • А чё компилить, это правда, есть такой отстой в 2003й версии. Переменная видна после цикла, это вызывает предупреждения от компилятора. Приходится давать разные имена T_T

                        Кстати, почему нельзя писать так:
                        if ((int i=SomeFunc())>=0)...
                        Ответить
              • operator float() { return g * (float)STEP(); }
                operator double() { return g * (double)STEP(); }
                operator int() { return g>>BP; }
                operator long() { return g>>BP; }

                А что он должен был выбрать? Если у него на выбор преобразования во все подряд, и std::abs принимает все подряд... Баг тут в говнокомпиляторе, который молча выбрал первый попавшийся вариант, и промолчал об этом.

                http://ideone.com/wnZG3
                Ответить
    • Короче, вы все сами видите, к чему приводят нахуй не нужные неявные приведения.
      В языке высокого уровня неявные приведения нахуй не нужны!
      Ответить
      • Нет. Я вот вижу тут, к чему приводит использование нахуй никому не нужных старых компиляторов. Еще бы в Turbo C++ откомпилил, и ругался на КРИВЫЕ КРЕСТОБЛЯДСКИЕ СТАНДАРТЫ.
        Ответить
        • В нормальном языке abs(f) скомпилилось бы, сразу выбрав шаблон для нужного типа и выдав ожидаемый результат. Потому что компилятору нормального языка не приходится ломать голову над вариантами неявных приведений.
          Ответить
          • как ты думаешь, если говнокласс предоставляет operator int () и operator double (), какой из нижеследующих соответствующих стандарту с++03 std::abs надо выбрать?
            int abs(int n);
            long abs(long n);
            float abs(float arg);
            double abs(double arg);
            long double abs(long double arg);
            Ответить
            • А чё, std::abs не шаблон разве?
              Ответить
              • нет
                это наследие от C library с дополнениями
                Ответить
                • Бляяяя, вот дерьмо...
                  Ответить
                  • С:
                    <stdlib.h>: int abs(int);
                    <math.h>: double fabs(double);
                    C++:
                    <cstdlib> <cmath> - The contents of these headers are the same as the Standard C library headers <math.h> and <stdlib.h> respectively, with the following additions:
                    * In addition to the int versions of certain math functions in <cstdlib>, C++ adds long overloaded versions of these functions, with the same semantics.
                    * In addition to the double versions of the math functions in <cmath>, C + + adds float and long double overloaded versions of these functions, with the same semantics.
                    * The added signatures are: // включил только интересующие нас abs
                    float abs (float);
                    float fabs (float);
                    double abs(double); // fabs()
                    long double abs (long double);
                    long double fabs (long double);
                    Ответить
                • Кстати, а почему его нельзя было сделать шаблоном? Работало бы для всех типов, у которых есть операторы < и унарный минус... И нет проблем с внезапными приведениями.
                  Ответить
                  • я слабоват в IЁЁЁ - что там произойдет при abs(NaN) и прочее
                    да и ассемблерно вот эти вот все перегрузки (5 штук) явно оптимально могут выполняться отдельно друг от друга
                    не знаю, чем руководствовался комитет - может, тем, что программист не обломится написать свой шаблонный abs, а может им самим было лень расписывать, что мол имплементация обязана сделать template <class T> T abs(T const &), а затем специфицироваться 5 раз - кстати нюанс, копию или константную ссылку брать
                    опять же, одно дело max(T const & t1, T const & t2), где объекты сравниваются сами с собой, а другое дело - сравниваются с числом 0, раз сравниваются с числом, значит пусть приводятся к числу самостоятельно
                    еще как причина - это всё описано в разделе Numerics library - C library, а если шаблон, то який же це це?
                    Ответить
                    • abs(NaN) всяко NaN... вроде как любая арифметика, у которой один из операндов NaN должна вернуть NaN. Специализировать или не специализировать - решать имплементирующему, т.к. это, в теории, повлияет только на эффективность.

                      А вот проблема с const & или value и совместимость с С - вполне могли послужить причиной...
                      Ответить
                      • Нет проблемы. Всегда const &. Замена на значение для простых типов - на совести компилятора.
                        Ответить
                    • Число ноль можно явно привести к нужному типу.
                      Ответить
                      • лучше уж использовать T() вместо T(0) - типа return (t < T()) ? -t : t;
                        однако, всё равно придется специализации писать, и эти специализации будут использовать const & t, что в общем случае приведет к передаче адреса аргумента, а не копии в регистр/стек - оптимизации в стандарте не описываются, насколько я знаю
                        так что если господин хочет шаблон - пусть пишет самостоятельно, благо он тривиален
                        Ответить
                        • А замена 2+2 на 4 в стандарте описана?
                          Закладываться на то, что const& может не стат значением для целых - тупо. В стандарте Ады-то эта оптимизация есть же...
                          Ответить
                          • в данном конкретном случае ты скорее прав
                            в общем случае, если компилятор не может заинлайнить какую-то функцию (а это легко может быть - тело функции может лежать в рантайм-либе), он не имеет права передавать int const & как значение через регистр
                            потому что в теле этой функции ты вдруг захочешь взять указатель аргумента, и тебе должно быть гарантировано получение реального адреса этого объекта
                            шаблонная функция обычно инлайнится (в той мере, в которой инлайнится другая нешаблонная inline функция)
                            вот если функция инлайнится, тогда любой нормальный компилятор, конечно, соптимизирует int const & до того, что нужно (обычно, будет пользоваться значением в регистре) - т.е. шаблонный abs(T const &) соптимизируется до передачи int через регистр

                            но в стандарте этого не написано (я не нашел) и вряд ли будет описано

                            с современным компилятором можно считать истиной - если программист сказал копию, значит внутри функции он получит нечто, которое будет вести себя как копия (если копия окажется иммутабельной, то оптимизирующий компилятор может передать ссылку на объект с гарантией того же результата), если программист сказал ссылку на объект, значит он получит нечто, ведущее себя как ссылка на объект (если нужен адрес, ты его получишь, если не нужен и не будет никакой разницы с копией - компилятор улучшит)

                            а что там в аде - то константные ссылки, то копии, - я из твоих объяснений тогда не понял ничего
                            Ответить
                            • > а что там в аде - то константные ссылки, то копии, - я из твоих объяснений тогда не понял ничего

                              А фигли понимать. Если указатель или целое - то по копии, другое - по указателю.
                              Для структур размером 4 байта не знаю.
                              Ответить
                              • т.е. float по указателю?
                                Ответить
                                • Не знаю, но логика и интуиция говорит, что по регистру ФПУ
                                  Ответить
                                  • если даже ты путаешься в показаниях, значит не всё так очевидно и прозрачно в аде с передачей параметров
                                    Ответить
                                    • Я стандарт не читал и дизасм не смотрел. Просто мне цитировали выдержки из стандарта. В целом можно утверждать, что Ада передаёт параметры оптимальным способом.
                                      Ответить
                          • и да, замена 2+2 на 4 в стандарте упоминается
                            см 5.19 Constant expressions
                            Ответить
      • С тем что неявные приведения - зло согласен. Но сверх-строгая типизация тоже не очень хороша. В той же Аде довольно геморно возиться с ней.
        Ответить
        • Уже заценил?
          Гемор только при работе с сишколибами.
          А так зато сразу ясно с каким типом работаем и не надо думать, что к чему приведётся.
          Ответить
          • Не заценил, всегда любил строгую типизацию (Ада, Паскаль, Модула, Оберон).

            Из-за этого от Си/Си++ долго плевался, но привык. Кодить можно, так сказать.
            Ответить
            • > Не заценил

              Тогда откуда знаешь, что в Аде геморно?
              Ответить
              • Как сказать то.

                Не заценил, а всегда любил...

                Имею ввиду что давно уже заценил аду.
                Ответить
                • А в какой среде заценял?
                  Ответить
                  • Без среды.

                    GNAT + SciTE.
                    Ответить
                    • Отлаживал чем?
                      Ответить
                      • Ничем. Отладчик это костыль для программирования перебором.
                        Ответить
                        • Эпичный тред в тему:
                          http://govnokod.ru/10331#comment139062
                          Подумалось о ГК как о вики с перекрёстными ссылками, чтобы можно было ссылаться на эпичные треды в виде
                          [[link/to/thread|отладчик не нужен]]
                          Ответить

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