【问题标题】:std::expf and std::logf not recognized by gcc 7.2.0gcc 7.2.0 无法识别 std::expf 和 std::logf
【发布时间】:2019-08-22 19:38:12
【问题描述】:

似乎 gcc(已尝试 7.2.0 和 5.4.0)没有 std::expfstd::logf - 请参阅 coliru sample。由于 cppreference 说它们是在 C++11 中添加的,是否有一些我缺少的 gcc 特定宏或者它们通常在 gcc 中缺少?

【问题讨论】:

  • 你的 g++ 命令行是什么?你需要添加-std=c++11来启用c++11
  • @Nidhoegger 我的机器上确实有标志,但没有将它们添加到 coliru,修复了示例,但标志并没有解决这个问题,因为我从一开始就拥有它们。
  • an open bug report on this 已经两年了。 C++17 标准要求 <cmath> 声明 std::expfstd::logf 等,但 libstdc++ 不符合要求(截至 2019 年 6 月)。见here.
  • libc++ 实现确实正确地声明了标识符,所以clang++ -std=c++17 -stdlib=libc++ 应该可以工作。

标签: c++11 gcc


【解决方案1】:

这是 GCC 附带的 libstdc++ 中的一个错误。它不完全符合 C++17 (as of v9.1.0 in June 2019)。 Ubuntu 默认使用的<cmath> 版本的版权声明说它最后一次更新是在 2016 年。版本 9.1.0 确实有一个#if __cplusplus > 201402L 部分,但它没有声明 C++17 所需的标识符。 There is an open bug report.

它从不在 std:: 命名空间中声明 expflogf(也不是 cosfsinf 等),即使 C++17 says it shall. C++11 standard 说:“定义为C 中的函数应定义为 C++ 标准库中的函数”,以及“使用外部链接声明的标准 C 库中的每个名称都保留给实现,以用作 extern "C" 链接的名称,在 namespace std 和在全局命名空间中。”但是,std::expf 等。 <cmath> 直到 P0175r1 in June 2016. 提供的函数表中都缺少这些函数,这显然是一个疏忽,但 GCC 始终只在全局命名空间中提供它们。

libc++ 库确实声明了它们,因此使用 clang++ -std=c++17 -stdlib=libc++ 编译应该可以工作。您也可以#include <math.h> 在全局命名空间中使用它们,或者在浮点参数上使用重载的exp()log() 等。

【讨论】:

    【解决方案2】:

    如果你

    #include <cmath>
    

    你会得到

    float       exp ( float arg );
    double      exp ( double arg );
    long double exp ( long double arg );
    double      exp ( IntegralType arg );
    
    float       log ( float arg );
    double      log ( double arg );
    long double log ( long double arg );
    double      log ( IntegralType arg );
    

    因此您可以只调用std::exp/std::log 并让编译器为您找出重载。如果您想调用不匹配的重载(例如,double 变量上的 float 重载),我发现在这些情况下添加 static_cast 会更加明确和清晰:

    double bla = ...;
    return std::exp(static_cast<float>(bla));
    

    无论你怎么写,这都是一个奇怪的结构(例如,为什么bla 不是以float 开头的?),将它隐藏在单字母函数名称后缀中对任何人都没有帮助。

    【讨论】:

    • 好的,这是一个有效的回退,只需 msvc 和 clang 接受 expf 和 logf 就好了:(
    • 关于后备的好技巧,不胜感激。
    【解决方案3】:

    GCC 的 &lt;cmath&gt; 在 全局命名空间,而不是 std::。在std:: 中,它声明explog 的重载为 效果一样。

    【讨论】:

      猜你喜欢
      • 2014-10-26
      • 2023-03-17
      • 2015-11-25
      • 1970-01-01
      • 2017-03-17
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      相关资源
      最近更新 更多