У меня есть смешанный код C ++ / C, который я построил на
a) Visual C ++ 2010 Express (бесплатная версия) на Win-7 x32.
b) Среда Cygwin / Gcc, установленная в Windows-7 Home Premium Edition x32. Версия gcc 3.4.4 (специальный cygming, gdc 0.12, с использованием dmd 0.125)
c) Ubuntu 10.04 Linux - GCC версии 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
У меня есть код, как показано ниже (его функция-член для моего пользовательского класса), которая вычисляет абсолютное значение переданного объекта myhalf-
myhalf::myhalfabs(myhalf a)
{
float tmp;
tmp = abs(a.value); //This abs is from math.h :- float abs(float)
return tmp;
}
Это отлично работает в MS - Visual C ++ 2010. abs () of -ve nos были возвращены правильно как + ve nos, имеющие то же значение. Как ни странно, когда я создавал этот код в b) среде Cygwin / gcc и c) упомянутом выше Linux-gcc 4.4.3, я получал ненужный вывод. Итак, запустил gdb, и после долгих усилий и «подхода к двоичному поиску» кода, чтобы решить, где что-то пошло не так, я нашел этот фрагмент кода, как показано выше:
tmp = abs(a.value);
, который странно себя ведет под cygwin / gcc.
Для чисел -ve abs () возвращал 0 (ноль). WTF ??
Затем, как обходной маневр, я избегал вызова abs () из stdlib и закодировал свой собственный abs, как показано ниже:
myhalf::myhalfabs(myhalf a)
{
float tmp;
unsigned int tmp_dbg;
// tmp = abs(a.value);
tmp_dbg = *(unsigned int*)(&a.value);
tmp_dbg = tmp_dbg & 0x7FFFFFFF;
tmp = *(float*)(&tmp_dbg);
return tmp;
}
Это отлично сработало на cygwin / gcc и linux-gcc, и вывод был желаемым конечно, он отлично работал на MS-Visual C ++ 2010.
Это весь Makefile для сборок cygwin / gcc и linux-gcc, которые я использую. Просто если кто-то там подозревает: -
OBJS= <all my obj files listed here explicitly>
HEADERS= <my header files here>
CFLAGS= -Wall
LIBS= -lm
LDFLAGS= $(LIBS)
#MDEBUG=1
ifdef MDEBUG
CFLAGS += -fmudflap
LDFLAGS += -fmudflap -lmudflap
endif
myexe: $(OBJS)
g++ $(OBJS) $(LDFLAGS) -o myexe
%.o: %.cpp $(HEADERS) Makefile
g++ $(CFLAGS) -c $<
clean:
rm -f myexe $(OBJS)
1] Что здесь происходит? Какова основная причина этой странной ошибки?
2] Я использую старую версию gcc на cygwin, в которой эта проблема называется известной ошибкой или чем-то в этом роде?
3] Известна ли эта функция float abs (float) быть устаревшим или что-то, заменяющее его более новой версией?
Любые указатели полезны.
Во-первых, abs () принимает и возвращает int
. Вам следует использовать fabs () , которая принимает и возвращает значение с плавающей запятой.
Итак, abs()
, который вы в конечном итоге вызываете, на самом деле является встроенной функцией GCC , которая возвращает int
, но, очевидно, принимает аргумент float
и возвращает 0
в этом случае.