- 1
- 2
- 3
Fixed f = 0.2;
f = std::abs(f);
std::cout << (float)f;
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+24
Fixed f = 0.2;
f = std::abs(f);
std::cout << (float)f;
Угадайте, чему будет равно f?
Fixed - тип из той же библиотеки, что и в http://govnokod.ru/11294
зрители замерли, завороженно глядя на неравную борьбу маленького героя, несущего свет, с огнедышащим крестоблядским чудовищем из преисподней
кто победит в этом кровопролитном поединке?
что вернет std::abs от исчадия ада?
верно ли, что бесстрашие граничит с безумием?
test.cxx:186:16: error: call of overloaded 'abs(Fixed&)' is ambiguous
GNU/Linux
ты ведь доволен выбором инструмента (окаменелое говно мамонта 2003 года), который из перегрузок abs(integer type) и abs(float type) выбрал не то, что ты хотел?
И еще и ничего об этом не сказал
от микрософта можно ожидать чего угодно
стандарт то в 2003 году допилили окончательно, наивно полагать, что в 2003 студии (7.1) четкая его поддержка (это же по сути багфикс 2002й .net студии - 7.0)
у меня на работе вообще переход с 6.0 в свое время был сделан сразу на 2005 (8.0), а 7.0/7.1 я видел только в институте
но Тарас лёгких путей не ищет, нашёл левую говнобиблиотеку, взял студию, которая на его селероне хоть как то ворочается, а в итоге виноваты крестобляди
В 2003 студии, если не ошибаюсь, нельзя писать так:
P.S. Тарас, попробуй закомпилить этот код, пожалуйста, раз уж компилятор под рукой.
Кстати, почему нельзя писать так:
if ((int i=SomeFunc())>=0)...
http://ideone.com/Tmc3n
а в выражении нельзя
А что он должен был выбрать? Если у него на выбор преобразования во все подряд, и std::abs принимает все подряд... Баг тут в говнокомпиляторе, который молча выбрал первый попавшийся вариант, и промолчал об этом.
http://ideone.com/wnZG3
В языке высокого уровня неявные приведения нахуй не нужны!
это наследие от 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);
да и ассемблерно вот эти вот все перегрузки (5 штук) явно оптимально могут выполняться отдельно друг от друга
не знаю, чем руководствовался комитет - может, тем, что программист не обломится написать свой шаблонный abs, а может им самим было лень расписывать, что мол имплементация обязана сделать template <class T> T abs(T const &), а затем специфицироваться 5 раз - кстати нюанс, копию или константную ссылку брать
опять же, одно дело max(T const & t1, T const & t2), где объекты сравниваются сами с собой, а другое дело - сравниваются с числом 0, раз сравниваются с числом, значит пусть приводятся к числу самостоятельно
еще как причина - это всё описано в разделе Numerics library - C library, а если шаблон, то який же це це?
А вот проблема с const & или value и совместимость с С - вполне могли послужить причиной...
однако, всё равно придется специализации писать, и эти специализации будут использовать const & t, что в общем случае приведет к передаче адреса аргумента, а не копии в регистр/стек - оптимизации в стандарте не описываются, насколько я знаю
так что если господин хочет шаблон - пусть пишет самостоятельно, благо он тривиален
Закладываться на то, что const& может не стат значением для целых - тупо. В стандарте Ады-то эта оптимизация есть же...
в общем случае, если компилятор не может заинлайнить какую-то функцию (а это легко может быть - тело функции может лежать в рантайм-либе), он не имеет права передавать int const & как значение через регистр
потому что в теле этой функции ты вдруг захочешь взять указатель аргумента, и тебе должно быть гарантировано получение реального адреса этого объекта
шаблонная функция обычно инлайнится (в той мере, в которой инлайнится другая нешаблонная inline функция)
вот если функция инлайнится, тогда любой нормальный компилятор, конечно, соптимизирует int const & до того, что нужно (обычно, будет пользоваться значением в регистре) - т.е. шаблонный abs(T const &) соптимизируется до передачи int через регистр
но в стандарте этого не написано (я не нашел) и вряд ли будет описано
с современным компилятором можно считать истиной - если программист сказал копию, значит внутри функции он получит нечто, которое будет вести себя как копия (если копия окажется иммутабельной, то оптимизирующий компилятор может передать ссылку на объект с гарантией того же результата), если программист сказал ссылку на объект, значит он получит нечто, ведущее себя как ссылка на объект (если нужен адрес, ты его получишь, если не нужен и не будет никакой разницы с копией - компилятор улучшит)
а что там в аде - то константные ссылки, то копии, - я из твоих объяснений тогда не понял ничего
А фигли понимать. Если указатель или целое - то по копии, другое - по указателю.
Для структур размером 4 байта не знаю.
см 5.19 Constant expressions
Гемор только при работе с сишколибами.
А так зато сразу ясно с каким типом работаем и не надо думать, что к чему приведётся.
Из-за этого от Си/Си++ долго плевался, но привык. Кодить можно, так сказать.
Тогда откуда знаешь, что в Аде геморно?
Не заценил, а всегда любил...
Имею ввиду что давно уже заценил аду.
GNAT + SciTE.