我有C++/C混合代码,我在此基础上构建
( a)视觉C++ 2010快车(免费版)上的Win-7 x32.
( b)安装在Windows7家庭高级版x32上的Cygwin/Gcc环境。gcc版本3.4.4 (特殊版,gdc 0.12,使用dmd 0.125)
c) Ubuntu 10.04 Linux- GCC版本4.4.3 (Ubuntu 4.4.3-4 ubuntu5)
我有如下代码(它是用户定义类的成员函数),它计算传递的对象myhalf的绝对值-
myhalf::myhalfabs(myhalf a)
{
float tmp;
tmp = abs(a.value); //This abs is from math.h :- float abs(float)
return tmp;
}在MS-VisualC++ 2010中,这是完美的工作方式。-ve nos的abs()被正确地返回为具有相同值的+ve。奇怪的是,当我在b) Cygwin/gcc环境& c) Linux-4 4.4.3上构建这个代码时,我得到了垃圾输出。因此,启动gdb,经过大量的努力和“二进制搜索方法”来确定代码从哪里开始出错后,我点击了如下所示的代码:
tmp = abs(a.value);在西格温/gcc的统治下表现得很奇怪。
对于-ve数字,abs()返回0(零)。WTF?
然后,作为一项工作,避免从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上工作得很好,输出也是理想的,当然,它在C++ 2010上运行得很好。
这是整个Makefile为cygwin/gcc和linux构建的,我使用。如果有人在那里发现什么可疑的东西:-
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)这是怎么回事?这个奇怪的虫子的根本原因是什么?
(2)我是不是用了一些老版本的gcc在cygwin上,这个问题就是所谓的臭虫之类的?
3]这个函数float (Float)是已知的被废弃的,还是一个新版本取代它的功能?
任何指针都是有用的。
发布于 2011-09-30 18:41:46
math.h有C版本的abs,它运行在int上。使用<cmath>进行C++重载,或者使用fabs()作为C浮点版本。
发布于 2011-09-30 18:40:25
首先,abs()获取并返回一个int。您应该使用fabs(),它接受并返回一个浮点值.
现在,您最后调用的abs()实际上是一个GCC built-in function,它返回一个int,但在这种情况下显然接受float参数并返回0。
发布于 2011-09-30 18:41:40
几乎可以肯定的是,在MSVC的情况下,它正在捕获C++ abs浮点重载(这可能是由于某种原因而被带入全局命名空间)。然后,在g++中,它不是获取C++版本(它不是隐式导入全局命名空间),而是运行并返回一个int的C版本,后者将输出截断为零。
如果您使用#include <cmath>并使用std::abs,那么它应该可以在所有平台上正常工作。
https://stackoverflow.com/questions/7614520
复制相似问题