【问题标题】:`cosf`, `sinf`, etc. are not in `std` [duplicate]`cosf`,`sinf`等不在`std`中[重复]
【发布时间】:2019-06-02 18:49:52
【问题描述】:

根据此处的讨论,我已将reported a bug 发送给 Ubuntu 开发人员。


在编译以下示例 c++ 程序时:

#include <cmath>
#include <stdio.h>

int main()
{
    printf("%f\n", std::cosf(0.0f));
}

我收到以下错误消息:error: ‘cosf’ is not a member of ‘std’

包括math.h 并使用非命名空间版本可以正常工作。怎么回事?

我在 Ubuntu 19.04 上使用 g++ 8.3.0-6ubuntu1。

我正在使用g++ --std=c++17 test.cpp 构建

【问题讨论】:

  • 你的编译命令是什么?只是一个光秃秃的g++ main.cpp
  • 我认为std::sinfstd::cosf 等是在 C++11 中添加的。您是否在启用 C++11 的情况下进行编译?
  • g++ --std=c++17 main.cpp
  • 在 Godbolt 上,使用 g++ 或 clang 与 libstdc++ 时会出错。它在使用 clang -stdlib=libc++ 时有效。
  • @Shawn C++17 要求它在那里,所以这个库比标准落后了几年。

标签: c++ gcc libstdc++


【解决方案1】:

该版本的库 (libstdc++8) 不完全符合 C++17。版权声明说它最后一次更新是在 2016 年。截至 2019 年 6 月,the latest upstream release 被窃听。它确实有一个 #if __cplusplus &gt; 201402L 部分,但它没有声明 C++17 所需的标识符。 There is an open bug report.

在Ubuntu上看/usr/include/c++/8/cmath,它包括&lt;math.h&gt;,为其函数取消定义一系列宏(C标准库需要)来访问它们的名字,将cosacos等导入到std:: 命名空间,然后将重载的 floatlong double 重载声明为 inline

它从不在std:: 命名空间中声明cosf,即使C++17 says it shall. C++11 standard 说,“在C 中定义为函数的名称应在C++ 标准库中定义为函数”,并且“使用外部链接声明的标准 C 库中的每个名称都保留给实现,以用作 extern "C" 链接的名称,无论是在 namespace std 还是在全局命名空间中。”但是,它没有明确说明std::expf 等人。必须支持直到P0175r1 in June 2016. 这显然是一个疏忽。

libc++ 库确实声明了它们,因此使用 clang++ -std=c++17 -stdlib=libc++ 编译应该可以工作。

【讨论】:

  • 如果它应该在那里,它只是一个错误。你能证明这一点吗?
  • @HWalters 请参阅 C++17 标准草案 N4659(最终免费提供的草案),第 1140 页。open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf
  • @BrennanVincent 谢谢。添加了您的引用。
  • @HWalters 所以现在我自己也不确定。 N3337工作草案没有这个要求,但是cppreference.com claims they’ve been there since C++11.这是最后一分钟的变化,还是网站出错了?
  • 在 C++11 (N3337) 中,它说“这些头文件的内容分别与标准 C 库头文件 &lt;math.h&gt;&lt;stdlib.h&gt; 相同,但有以下更改:”。 C 版本确实包含 cosf(在 C99 中添加,这就是 C++11 中“标准 C”的含义),并且“以下更改”没有说任何会排除 cosf 的内容。我认为 cosf 没有在表 119 中列出只是一个疏忽。
猜你喜欢
  • 2012-08-12
  • 1970-01-01
  • 2012-03-10
  • 2019-09-10
  • 1970-01-01
  • 2016-08-28
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多