std::expf和std::logf不被gcc 7.2.0识别

aemubtdh  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(135)

看起来gcc(尝试7.2.0和5.4.0)没有std::expfstd::logf-参见colirus sample。由于cppreference说它们是在C++11中添加的,是不是有一些gcc特定的宏我遗漏了,或者它们在gcc中普遍缺失?

quhf5bfb

quhf5bfb1#

这是libstdc中的一个bug,它随GCC一起提供。它不完全符合C17(as of v9.1.0 in June 2019)。Ubuntu默认使用的<cmath>版本上的版权声明说,它最后一次更新是在2016年。9.1.0版本确实有一个#if __cplusplus > 201402L部分,但它没有声明C17所需的标识符。There is an open bug report.
它从不在std::命名空间中声明expflogf(也不声明cosfsinf等),即使C
17说它应该这样做。C++11 standard说,“在C中定义为函数的名称应定义为C++标准库中的函数”,并且“标准C库中使用外部链接声明的每个名称都保留给实现,以用作extern "C"链接的名称,无论是在namespace std中还是在全局命名空间中。从<cmath>直到P0175r1 in June 2016.提供的函数表中缺失这显然是一个疏忽,但GCC一直只在全局名称空间中提供它们。
libc++库声明了它们,所以用clang++ -std=c++17 -stdlib=libc++编译应该可以。您也可以在全局命名空间中使用#include <math.h>,或者使用重载的exp()log()等。float参数。

更新

截至2023年8月,libc++终于有了一个补丁,等待提交。

wj8zmpe1

wj8zmpe12#

如果你

#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开始开始?),将其隐藏在单字母函数名后缀中对任何人都没有帮助。

pbgvytdp

pbgvytdp3#

GCC的<cmath>在全局命名空间中声明了函数expflogf以及它们的C Library kin,而不是std::。在std::中,它声明了explog的重载,效果相同。

相关问题