Based on the discussion here, I have reported a bug to the Ubuntu developers.
When compiling the following sample c++ program:
#include <cmath>
#include <stdio.h>
int main()
{
printf("%f\n", std::cosf(0.0f));
}
I get the following error message: error: ‘cosf’ is not a member of ‘std’
Including math.h
and using the non-namespaced version works fine. What is going on?
I am using g++ 8.3.0-6ubuntu1 on Ubuntu 19.04.
I am building with g++ --std=c++17 test.cpp
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
In C++, a namespace is a collection of related names or identifiers (functions, class, variables) which helps to separate these identifiers from similar identifiers in other namespaces or the global namespace. The identifiers of the C++ standard library are defined in a namespace called std .
That version of the library (libstdc++8) is not fully conforming to C++17. The copyright notice says it was last updated in 2016. As of June 2019, the latest upstream release is bugged. It does have a #if __cplusplus > 201402L
section, but it doesn’t declare the identifiers required by C++17. There is an open bug report.
Looking at /usr/include/c++/8/cmath
on Ubuntu, it includes <math.h>
, undefines a series of macros for its functions (required by the C standard library) to access their names, imports cos
, acos
, etc. into the std::
namespace, and then declares the overloaded float
and long double
overloads as inline
.
It never declares cosf
within the std::
namespace, even though C++17 says it shall. The C++11 standard says, “Names that are defined as functions in C shall be defined as functions in the C++ standard library,” and “Each name from the Standard C library declared with external linkage is reserved to the implementation for use as a name with extern "C"
linkage, both in namespace std
and in the global namespace.” However, it does not explicitly state that std::expf
et al. must be supported until P0175r1 in June 2016. This was apparently an oversight.
The libc++ library does declare them, so compiling with clang++ -std=c++17 -stdlib=libc++
should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With