gol*_*ean 23 c++ standard-library
我有构建的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,使用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;
}
Run Code Online (Sandbox Code Playgroud)
这在MS-Visual C++ 2010中完全按照需要工作.-ve nos的abs()被正确地返回为+ ve nos具有相同的值.奇怪的是,当我在b)Cygwin/gcc环境&c)上面提到的Linux-gcc 4.4.3上构建这个代码时,我得到了垃圾输出.所以激发了gdb,经过大量的汗水和代码上的"二元搜索方法"来决定它出错的地方,我点击了上面这段代码:
tmp = abs(a.value);
Run Code Online (Sandbox Code Playgroud)
这在cygwin/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;
}
Run Code Online (Sandbox Code Playgroud)
这在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)
Run Code Online (Sandbox Code Playgroud)
1]这里发生了什么?这个奇怪的bug的根本原因是什么?
2]我在cygwin上使用了一些旧版本的gcc,这个问题是已知的bug还是什么?
3]这个函数float abs(float)是否已被弃用或者某个更新版本取代它?
任何指针都很有用.
Dav*_*ger 31
math.h其C版本abs在ints 上运行.使用<cmath>的C++重载或使用fabs()为C浮点版本.
几乎可以肯定的是,在你的MSVC情况下,它正在拾取C++ abs浮点重载(由于某种原因可能会被带入全局命名空间).然后在g ++中它没有拿起C++版本(它没有隐式导入到全局命名空间中),而是处理的C版本并返回一个int然后将输出截断为零的版本.
如果您#include <cmath>使用std::abs它应该可以在所有平台上正常工作.
| 归档时间: |
|
| 查看次数: |
11702 次 |
| 最近记录: |