< cmath>在< math.h>中隐藏isnan在C ++ 14/C ++ 11中? [英] <cmath> hides isnan in <math.h> in C++14 / C++11?
本文介绍了< cmath>在< math.h>中隐藏isnan在C ++ 14/C ++ 11中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在这里有一个小型测试应用程序,它使用< math.h>
中的 isnan
:
I have here a small test app which uses isnan
from <math.h>
:
#include <iostream>
#include <math.h>
int main()
{
double d = NAN;
std::cout << isnan(d) << '\n';
return 0;
}
构建并运行3种不同的标准:
$ g++ -std=c++98 main.cpp; ./a.out
1
$ g++ -std=c++11 main.cpp; ./a.out
1
$ g++ -std=c++14 main.cpp; ./a.out
1
现在我们还包含< cmath>
,并同时测试 isnan
和 std :: isnan
:
Now we also include <cmath>
, and test with both isnan
and std::isnan
:
#include <iostream>
#include <cmath>
#include <math.h>
int main()
{
double d = NAN;
std::cout << std::isnan(d) << '\n';
std::cout << isnan(d) << '\n';
return 0;
}
构建并运行:
C ++ 98可以运行
$ g++ -std=c++98 main.cpp; ./a.out
1
1
未找到C ++ 11和C ++ 14,未找到 isnan
.
$ g++ -std=c++11 main.cpp
main.cpp: In function ‘int main()’:
main.cpp:10:25: error: ‘isnan’ was not declared in this scope
std::cout << isnan(d) << '\n';
^
main.cpp:10:25: note: suggested alternative:
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:641:5: note: ‘std::isnan’
isnan(_Tp __x)
^
$ g++ -std=c++14 main.cpp
main.cpp: In function ‘int main()’:
main.cpp:10:25: error: ‘isnan’ was not declared in this scope
std::cout << isnan(d) << '\n';
^
main.cpp:10:25: note: suggested alternative:
In file included from main.cpp:3:0:
/usr/include/c++/5/cmath:641:5: note: ‘std::isnan’
isnan(_Tp __x)
^
请注意,包含顺序并不重要.如果我在< math.h>
之前或之后加上< cmath>
,则结果是相同的.
Note the order of inclusion is not important. If I include <cmath>
before <math.h>
or after, the result is the same.
问题
- 为什么
isnan
不见了? - 无需回去更改旧代码即可在新标准下进行编译,有什么方法可以解决此问题?
推荐答案
Briefly summarizing the pertinent points, mostly from Jonathan Wakely's excellent blog post:
- glibc< 2.23的
math.h
声明了与C99/C ++ 11版本不兼容的过时的X/Openint isnan(double);
(bool isnan(double);
). - glibc 2.23的
math.h
通过不声明C ++ 11或更高版本中的isnan
函数来解决此问题. - 所有这些都仍然定义了
isnan
宏.#include< cmath>
会按照C ++标准的要求更改该宏. - GCC 6的libstdc ++提供了其自己的特殊
math.h
头,该头在全局命名空间中声明了bool isnan(double);
(除非libcmath).h
声明过时的签名),并按标准要求对宏进行修改. - 在GCC 6之前,
#include< math.h>
只是包含了libc中的标头,因此该宏不会被破坏. -
#include< cmath>
总是对宏进行操作.
- glibc <2.23's
math.h
declares the obsolete X/Openint isnan(double);
that is incompatible with the C99/C++11 version (bool isnan(double);
). - glibc 2.23's
math.h
fixes this by not declaring theisnan
function in C++11 or later. - All of them still define an
isnan
macro.#include <cmath>
nukes that macro as required by the C++ standard. - GCC 6's libstdc++ provides its own special
math.h
header that declares abool isnan(double);
in the global namespace (unless the libcmath.h
declares the obsolete signature) and also nukes the macros as required by the standard. - Before GCC 6,
#include <math.h>
simply included the header from your libc, so the macro isn't nuked. #include <cmath>
always nukes the macros.
在C ++ 11模式下的最终结果:
Net result, in C++11 mode:
glibc < 2.23, GCC < 6: <math.h> uses the macro; <cmath> uses obsolete signature
glibc >= 2.23, GCC < 6: <math.h> uses the macro; <cmath> results in error
glibc < 2.23, GCC >= 6: <math.h> and <cmath> use obsolete signature
glibc >= 2.23, GCC >= 6: <math.h> and <cmath> use standard signature
这篇关于< cmath>在< math.h>中隐藏isnan在C ++ 14/C ++ 11中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文