gcc 7.2.0无法识别std :: expf和std :: logf

时间:2019-04-01 15:19:42

标签: c++11 gcc

似乎gcc(尝试7.2.0和5.4.0)没有std::expfstd::logf-请参阅coliru sample。由于cppreference表示它们是在C ++ 11中添加的,因此我是否缺少某些gcc特定的宏,或者它们在gcc中总体上还是缺少的?

4 个答案:

答案 0 :(得分:2)

这是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.

即使C++17 says it shall.,它也不会在expf命名空间内声明logfcosf(也sinfstd::等)。 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()等。

答案 1 :(得分:1)

如果您

#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,然后让编译器为您找出重载。如果您想调用不匹配的重载(例如,float变量上的double重载),我发现在这些情况下添加static_cast更为明确和明确:

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

无论用哪种方式编写,这都是一个奇怪的构造(例如,为什么bla不是一个float?),并且将其隐藏在单字母函数名称后缀中是没有用的任何人。

答案 2 :(得分:0)

要使g ++使用C ++ 11,您需要添加

-std=c++11

到编译器命令行。

例如:

g++ -o test -std=c++11 test.cc

答案 3 :(得分:0)

GCC的<cmath>在函数中声明函数expflogf以及它们的C库亲属。 全局名称空间,而不是std::。在std::中,将explog的重载声明为 同样的效果。