Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ gcc `floorf` not a member of `std`?

Tags:

c++

gcc

c++11

I have the following piece of code:

#include <cmath>

float foo(float x, unsigned int m, float q = 0.0f)
{
    return std::floorf(x * float(m) + q);
}

Now when I try to compile this with g++ 5.4.0 and options -std=c++11 I get an error saying ‘floorf’ is not a member of ‘std’.

Now it is my understanding that clause 26.8 of the C++11 standard mandates that the standard C++ library header <cmath> declare the same set of functions as the standard C library header <math.h>, albeit in the namespace std; and that clause 1.2 specifies that "C" is to be interpreted as C99; and that clause 7.12.9.2 of the C99 standard mandates that the standard C library header <math.h> declare a function float floorf(float).

So by that reasoning <cmath> should declare a function float std::floorf(float), which to the best of my knowledge should be a match for my code.

What gives? Am I missing something here?

(I know C++11 also defines a float std::floor(float); however, I've recently made the discovery that the f-suffixed variants of float functions are generally slightly faster, so I'd prefer to specifically invoke floorf().)

like image 980
Christoph Lipka Avatar asked Feb 11 '19 02:02

Christoph Lipka


1 Answers

I believe that you have indeed found a bug in the header. On my GCC, using the GNU C library (glibc), I can work around by dropping out of std:: into the global namespace, changing

    return std::floorf(x * float(m) + q);

to

    return ::floorf(x * float(m) + q);

The workaround works because floorf() belongs to the C standard library, so it has a global symbol in glibc. Since the workaround uses the global symbol, which C++11 allows but does not require to exist, the workaround is nonportable. Nevertheless, for glibc, it appears to work.

The workaround could be made portable, if you wish, by changing #include <cmath> to #include <math.h> and (as far as I know) dropping all your C-math-library calls into the global namespace. It would still be just a workaround, though.

You may go ahead and report this as a bug at: https://gcc.gnu.org/bugzilla/. Moreover, to be taken more seriously by the GCC team, you can link the bug report back here to show that several competent pairs of eyes have already looked at the problem. Meanwhile, nice work.

like image 153
thb Avatar answered Nov 02 '22 04:11

thb