ここでの議論に基づいて、私は バグを報告 を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
で構築しています
ライブラリのそのバージョン( libstdc ++ 8 )はC++ 17に完全には準拠していません。著作権表示には、2016年に最後に更新されたと記載されています。2019年6月の時点で、 最新のアップストリームリリース にバグがあります。 #if __cplusplus > 201402L
セクションはありますが、C++ 17で必要な識別子を宣言していません。 未解決のバグレポートがあります。
Ubuntuの/usr/include/c++/8/cmath
を見ると、<math.h>
が含まれており、その関数に一連のマクロを定義解除して(C標準ライブラリで必要)、名前にアクセスしてcos
、acos
などをstd::
名前空間に追加し、オーバーロードされたfloat
およびlong double
オーバーロードをinline
として宣言します。
C++ 17はそれがそうしなければならないと述べていますが、cosf
をstd::
名前空間内で宣言することはありません。C++ 11標準 は、「Cで関数として定義された名前は、C++標準ライブラリで関数として定義される」、および「標準の各名前外部リンケージで宣言されたCライブラリは、extern "C"
リンケージでの名前として使用するために、namespace std
とグローバル名前空間の両方で実装用に予約されています。ただし、std::expf
et al。と明記されていません。 2016年6月の P0175r1までサポートされる必要があります。 これは明らかに見落としでした。
libc ++ ライブラリはそれらを宣言しているので、clang++ -std=c++17 -stdlib=libc++
を使用したコンパイルは機能するはずです。