【发布时间】:2011-11-28 16:41:00
【问题描述】:
我有我构建的 C++/C 混合代码
a) Win-7 x32 上的 Visual C++ 2010 Express(免费版)。
b) 安装在 Windows-7 Home 高级版 x32 上的 Cygwin/Gcc 环境。 gcc 3.4.4 版本(cygming special, gdc 0.12, using 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 中可以正常工作。 -ve nos 的 abs() 正确返回为具有相同值的 +ve nos。 奇怪的是,当我在上面提到的 b) Cygwin/gcc 环境和 c) Linux-gcc 4.4.3 上构建此代码时,我得到了垃圾输出。所以启动了 gdb,经过大量的汗水和对代码的“二进制搜索方法”以确定它开始出错的地方,我点击了这段代码,如上所示:
tmp = abs(a.value);
在 cygwin/gcc 下表现异常。
对于 -ve 数字 abs() 返回 0(零)。什么鬼??
然后作为一种解决方法,避免从 stdlib 调用 abs(),并将我自己的 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 上运行良好。
这是我使用的 cygwin/gcc 和 linux-gcc 构建的整个 Makefile。只是如果有人怀疑那里有什么可疑之处:-
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] 我是否在 cygwin 上使用了一些旧版本的 gcc,它存在已知错误或其他问题?
3] 这个函数 float abs(float) 是否已被弃用或被新版本取代?
任何指针都是有用的。
【问题讨论】:
-
如果你创建一个小测试用例会很有用,这样每个人都可以拿sn-p,不加修改地编译,自己看看你的意思。
-
abs()函数通常返回一个int,您将它分配给float。你确定这不是你问题的根源吗? -
你和
fabs有同样的行为吗? -
我同意 larsks - 有一个
fabs()函数专门用于浮动。改用它有帮助吗? -
@littleadv - 将在周一尝试晶圆厂。会更新。 larsks - 见 math.h 。 abs 可以接受 float return float。
标签: c++ standard-library