我这里有一个小测试应用程序,它使用中的isnan:

#include

#include

int main()

{

double d = NAN;

std::cout << isnan(d) << '

';

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

现在我们还包括,并使用isnan和std::isnan进行测试:

#include

#include

#include

int main()

{

double d = NAN;

std::cout << std::isnan(d) << '

';

std::cout << isnan(d) << '

';

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) << '

';

^

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) << '

';

^

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)

^

请注意,包含的顺序并不重要。 如果我在之前或之后包含,结果是相同的。

问题

为什么isnan消失了?

无需返回并更改旧代码以在新标准下编译,有没有办法解决这个问题?

Clang是使用libc ++,还是与gcc相同的libstdc ++?

@ildjarn ldd表示它是相同的(/usr/lib/x86_64-linux-gnu/libstdc++.so.6)。我编辑了这个问题以删除clang部分。

奇怪的问题..如果你交换包括cmath和math.h的字符串怎么办?至于我,我避免使用像cmath这样的c *标题

@AntonMalyshev你问的包含顺序?这没什么区别。

您使用的是什么版本的编译器?我无法用col ++重现g ++或clang。

@AntonMalyshev无法避免使用c *标头 - 这是旧代码,需要构建为使用更新标准构建的更大代码库的一部分

@NathanOliver我正在使用g++ 5.4.0。 glibc版本是2.23

哼。显然coliru使用ldd(Ubuntu EGLIBC 2.15-0ubuntu10.13)2.15

@NathanOliver关注你的评论我试过Wandbox。它没有gcc-5.4.0但它确实有5.3.0和6.1.0,我也无法复制......非常奇怪!

不要同时使用cmath和math.h ...

看起来它可能是图书馆的一个错误。 gcc.godbolt.org在4.9.2到5.3之间失败但在6.1上工作

@Ven,我不是。有问题的代码使用math.h。但是,我假设其他一些包含的内容包括最终包含cmath的内容,因此两者都在范围内。因此编译失败,因此我编写这个小应用程序来诊断正在发生的事情

@NathanOliver非常有趣! gcc.godbolt.org无法编译5.3,而wandbox适用于5.3。

非常离奇。看看这种不一致的原因是多么有趣。对不起,我只能混淆问题:)

@NathanOliver不,谢谢你帮忙确认我不是疯了!我会看看bugzilla,看看能不能找到任何东西

@NathanOliver我在Centos gcc-4.9.1和gcc-5.2.1上运行它,它适用于两者。在Ubuntu gcc-4.9.3上运行它,但gcc-5.4.0没有。鉴于godbolt对某些人失败了,但是wandbox没有...好吧,我不知道该怎么想?!

@SteveLorimer如果你在几天内没有找到任何东西给我一个ping,我会给你一个赏金。我真的很想知道发生了什么。

简要总结相关要点,主要来自Jonathan Wakely的优秀博客文章:

glibc <2.23的math.h声明过时的X / Open int isnan(double);与C99 / C ++ 11版本(bool isnan(double);)不兼容。

glibc 2.23的math.h通过不在C ++ 11或更高版本中声明isnan函数来解决这个问题。

所有这些仍然定义了一个isnan宏。 #include根据C ++标准的要求核对该宏。

GCC 6的libstdc ++提供了自己的特殊math.h头,它在全局命名空间中声明了一个bool isnan(double);(除非libc math.h声明了过时的签名),并且还按照标准的要求来核对宏。

在GCC 6之前,#include只包含libc中的标题,因此宏不会被破坏。

#include总是核心宏。

净结果,在C ++ 11模式下:

glibc <  2.23, GCC <  6: uses the macro; uses obsolete signature

glibc >= 2.23, GCC <  6: uses the macro; results in error

glibc <  2.23, GCC >= 6: and use obsolete signature

glibc >= 2.23, GCC >= 6: and use standard signature

@NathanOliver你看到了这个答案吗?

谢谢 - 非常翔实!

@SteveLorimer我现在有。 谢谢T.C. 另一个很好的答案。

如果从GCC查看,它有:

. . .

#include

. . .

#undef isnan

这就是订单无关紧要的原因 - 无论何时#include,都是自动包含的,其内容是(部分)核心的。

由于#ifndef _MATH_H,尝试再次包含它将无效。

现在,标准对这种行为有什么看法?

[depr.c.headers]:

... every C header, each

of which has a name of the form name.h, behaves as if each name placed

in the standard library namespace by the corresponding cname header is

placed within the global namespace scope. It is unspecified whether

these names are first declared or defined within namespace scope

([basic.scope.namespace]) of the namespace std and are then injected

into the global namespace scope by explicit using-declarations

([namespace.udecl]).

[ Example: The header assuredly provides its declarations

and definitions within the namespace std. It may also provide these

names within the global namespace. The header assuredly

provides the same declarations and definitions within the global

namespace, much as in the C Standard. It may also provide these names

within the namespace std. — end example ]

所以在全局命名空间中不提供isnan是可以的。

但是当它们都被包含在一个编译单元中时,它应该是一个灰色区域,尽管可以说上面的语句暗示两个版本必须互操作,在这种情况下它将是GCC / libstdc ++(某些版本)中的错误。

math.h中的许多函数实际上都是宏。由于这不是惯用的c ++,标头cmath包含以下代码:

...

#undef isinf

#undef isnan

#undef isnormal

...

然后将所有那些未定义的宏实现为namespace std中的函数。对于gcc 6.1.1,这至少是正确的。这就是你的编译器找不到isnan的原因。

我可以在godbolt上编译gcc-6.1上的std::isnan和isnan

如果它与undef有问题,那么包含的顺序就很重要,但这并不重要

@AntonMalyshev:为什么订单很重要? cmath几乎总是包含math.h,它将有一个标题保护 - 它将始终包含一次,并且只包含一次。

c语言isnan,关于c ++:隐藏了C ++ 14 / C ++ 11中中的isnan? | 码农家园相关推荐

  1. Python|SQL详解之DDL|DML|DQL|DCL|索引|视图、函数和过程|JSON类型|窗口函数|接入MySQL|清屏|正则表达式|executemany|语言基础50课:学习(14)

    文章目录 系列目录 原项目地址 第41课:SQL详解之DDL 建库建表 删除表和修改表 第42课:SQL详解之DML insert操作 delete 操作 update 操作 完整的数据 第43课:S ...

  2. R语言ggplot2可视化分面图、在分面图中的每个直方图中添加均值文本标签、添加均值红色竖线

    R语言ggplot2可视化分面图.在分面图中的每个直方图中添加均值文本标签.添加均值红色竖线 目录

  3. R语言ggplot2可视化:可视化堆叠的直方图、在bin中的每个分组部分添加数值标签、使用position_stack函数设置

    R语言ggplot2可视化:可视化堆叠的直方图.在bin中的每个分组部分添加数值标签.使用position_stack函数设置 目录

  4. R语言ggplot2可视化:可视化箱图、在箱图中添加抖动数据点(Dot + Box Plot)、自定义抖动数据点的大小、颜色、数据点分布在箱图中间、添加主标题、副标题、题注信息

    R语言ggplot2可视化:可视化箱图.在箱图中添加抖动数据点(Dot + Box Plot).自定义抖动数据点的大小.颜色.数据点分布在箱图中间.添加主标题.副标题.题注信息 目录

  5. R语言可视化散点图(scatter plot)图、为图中的部分数据点添加标签、ggrepel包来帮忙

    R语言可视化散点图(scatter plot)图.为图中的部分数据点添加标签.ggrepel包来帮忙 目录

  6. R语言可视化散点图(scatter plot)、并在散点图中叠加回归曲线、叠加lowess拟合曲线(linear and lowess fit lines)、使用plot、line、abline函数

    R语言可视化散点图(scatter plot).并在散点图中叠加回归曲线.叠加lowess拟合曲线(linear and lowess fit lines).使用plot函数.line函数和ablin ...

  7. R语言ggplot2可视化:为层次聚类树状图dendrogram中的簇进行着色、在树状图dendrogram中为不同的层次聚类簇配置不同的色彩

    R语言ggplot2可视化:为层次聚类树状图dendrogram中的簇进行着色.在树状图dendrogram中为不同的层次聚类簇配置不同的色彩 #层次聚类树状图dendrogram labs = pa ...

  8. R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量、将异常离散编码转化为NA值

    R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:基于条件判断创建布尔型指示变量.将异常离散编码转化为NA值 目录

  9. R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:使用na_if()函数将0值替换为NA值、负收入替换为NA值

    R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:使用na_if()函数将0值替换为NA值.负收入替换为NA值 目录

最新文章

  1. 学习Linux系统的十一点建议
  2. 大牛的距离(笑cry)精简算法
  3. 汤普森算法_火箭队闹剧不断!自编算法向NBA申诉:这个公式要在NBA普及!
  4. 北邮OJ 1027. 16校赛-Archer in Archery
  5. SQL重复记录查询(常用)
  6. 违反Apache 2.0许可证再分发被指控,火山引擎回应
  7. uniapp 获取图片的高度_uni-app获取元素高度等信息,并设置元素top信息
  8. 《树莓派开发实战(第2版)》——2.9 利用RDP远程控制树莓派
  9. DB2 Vs MySQL系列 | 体系架构对比
  10. Python 3.9 正式版要来了,会有哪些新特性?
  11. 关系型数据库中主键(primary key)和外键(foreign key)的概念。
  12. 面向对象分析和设计的几个关键步骤_超市设计中不容忽视的小细节
  13. 群晖 上传 源文件不存在_群晖NAS配多大容量硬盘合适?
  14. SecureCRT下载和设置
  15. 游戏契合度提示音_产品/市场契合度
  16. Chrome插件--IDM
  17. android scheme测试,android URLScheme的设置、调试和捕获
  18. dreamweaver网页制作,主题呼吁人们保护动物
  19. 杨凌职业技术学院计算机专业宿舍,杨凌职业技术学院宿舍怎么样
  20. 计算方法/数值分析牛顿下山法C/C++实现方法

热门文章

  1. 已重置应用默认设置html,教大家Win10已重置应用默认设置的解决方法
  2. 微信小程序 分享登录的问题
  3. 【数字IC手撕代码】Verilog半整数分频|题目|原理|设计|仿真
  4. 为什么很多之前炒股的人,在接触外汇后,都倾向于做外汇呢?
  5. 新手推广自己的APP,可用的渠道有哪些?
  6. 浅谈PPM (Project Portfolio Management) - 1
  7. 八爪鱼爬取搜索引擎链接列表后如何循环点击每个列表里的特定元素呢?
  8. SQL Delete 语句(删除表中的记录)
  9. 第6章 关系数据理论—多值依赖和4NF
  10. 数据挖掘中的利器--XGBoost理论篇