Bug 79700

Summary: std::fabsf and std::fabsl missing from <cmath>
Product: gcc Reporter: Jonathan Wakely <redi>
Component: libstdc++Assignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: 3dw4rd, daniel.kruegler, kip, marc.mutz, webrown.cpp
Priority: P3 Keywords: rejects-valid
Version: 6.3.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2017-02-24 00:00:00

Description Jonathan Wakely 2017-02-24 02:31:50 UTC
#include <cmath>

using std::fabsf;
using std::fabsl;

abs.cc:3:12: error: ‘std::fabsf’ has not been declared
 using std::fabsf;
            ^~~~~
abs.cc:4:12: error: ‘std::fabsl’ has not been declared
 using std::fabsl;
            ^~~~~

These are required by C++17 (and maybe implicitly by C++11, although it's not very clear)
Comment 1 Jonathan Wakely 2017-02-24 02:50:32 UTC
Also:

modf{f,l}
acos{f,l}
asin{f,l}
atan2{f,l}
cos{f,l}
sin{f,l}
tan{f,l}
cosh{f,l}
sinh{f,l}
tanh{f,l}
exp{f,l}
frexp{f,l}
ldexp{f,l}
log{f,l}
log10{f,l}
pow{f,l}
sqrt{f,l}
ceil{f,l}
floor{f,l}
fmod{f,l}
Comment 2 Jonathan Wakely 2019-02-11 10:16:59 UTC
*** Bug 89279 has been marked as a duplicate of this bug. ***
Comment 3 JMB 2019-09-05 14:18:28 UTC
The bug is still present with g++ 8.3.0 on Ubuntu 19.04
(g++ (Ubuntu 8.3.0-6ubuntu1) 8.3.0) as tested with sqrtl.
As g++ is not conformant with c++11 (AFAIK):
  std::sqrt(n)
will result in the error message:
  error: ‘sqrtl’ is not a member of ‘std’
while using '# include <ctime>',
this bug should be fixed.
Otherwise please give a short comment to this bug report explaining why this can  not or should not be fixed.
Especially if giving C++14 as default ...
Comment 4 Jonathan Wakely 2019-09-05 14:47:40 UTC
(In reply to JMB from comment #3)
> this bug should be fixed.

Yes, we know. That's why there's a bug report.

> Otherwise please give a short comment to this bug report explaining why this
> can  not or should not be fixed.

Of course it should be fixed, that's why there's a bug report and it hasn't been closed. But we have lots of bugs and finite resources.

> Especially if giving C++14 as default ...

As I said above, it's not actually clear if this is required by C++11 and C++14. The function sqrtl is not mentioned at all in the C++14 standard. It's definitely required by C++17, but that isn't enabled by default.
Comment 5 Kip Warner 2020-12-22 23:31:51 UTC
I am experiencing the same problem with GCC 10.2.0.

I have included <cmath> and I am attempting to rely on std::ceilf. g++(1) bails with:

error: ‘ceilf’ is not a member of ‘std’; did you mean ‘ceil’

$ g++ --version
g++ (Ubuntu 10.2.0-13ubuntu1) 10.2.0
Comment 6 Jonathan Wakely 2020-12-23 08:34:14 UTC
As it says, you can just use std::ceil.
Comment 7 Kip Warner 2020-12-23 17:33:47 UTC
Not if I want any certainty at compile time that it is single precision.
Comment 8 Jonathan Wakely 2020-12-23 20:48:10 UTC
If you call std::ceil with a float, you get the ceil(float) overload. If you don't call it with a float, you haven't got subtle precision anyway and calling ceil didn't change that.

If you need ceilf you can include <math.h> and call ceilf.
Comment 9 Jonathan Wakely 2020-12-23 20:52:17 UTC
And calling ceilf(x) doesn't give you any certainty of single precision, because if x is a double then it will still work, but you're now doing a conversion from double to float.

If you already know x is a float, then std::ceil(x) is single precision. If you don't know it's a float, using ceilf doesn't change that. The only certainty you have is x will be converted to float.
Comment 10 Kip Warner 2020-12-23 22:06:17 UTC
Thanks Jonathan, but I disagree. The point is that the caller might be wrong in any number of assumptions. The library designers were in agreement, hence why there is an explicit ceilf function.
Comment 11 Jonathan Wakely 2020-12-23 23:04:08 UTC
Nope, ceilf comes from C, which has no overloading.

C++ doesn't need separate names for ceil, ceilf and ceill, so you just have std::ceil.

The fact std::ceilf exists at all is just for consistency with C, not because "the library designers" considered it important. That's why it wasn't even mentioned in C++98, C++03, C++11, or C++14.

We will add all the functions listed above in this bug, because they're meant to be there, but they are not essential. You can use std::ceil((float)x) or ::ceilf(x) as a workaround with identical semantics.
Comment 12 Kip Warner 2020-12-23 23:09:59 UTC
I didn't say STL. I said library designers which includes the standard C runtime. And no, I don't agree with you. Separate names are helpful for greater certainty. As for std::ceilf existing just for consistency with C, that's speculative and, in my view doubtful.
Comment 13 Jonathan Wakely 2020-12-24 00:42:39 UTC
(In reply to Kip Warner from comment #12)
> I didn't say STL. I said library designers which includes the standard C
> runtime.

Why a particular name is used by C is not relevant to C++. The function is in C++ because it was inherited from C99, with no discussion or consideration about suitability for the C++ library.

> And no, I don't agree with you. Separate names are helpful for
> greater certainty. As for std::ceilf existing just for consistency with C,
> that's speculative and, in my view doubtful.

It's not speculative. I am certain that ceilf was never once mentioned in a WG21 proposal (or minutes of WG21 meetings) until https://wg21.link/p0175 proposed explicitly naming it in the C++ standard for consistency with the contents of <math.h> in C99.

It had previously been mentioned in https://wg21.link/lwg289 which concluded that ceilf etc were *not* part of the C++ standard (which meant C++98 at the time). There was no subsequent design decision to explicitly add it to C++, it was brought it when C++ rebased its library on the C99 library. In other words, for consistency with C.

Your time would be better spent submitting a patch to add it to libstdc++ rather than trying to convince me of its history in the C++ library.
Comment 14 Kip Warner 2020-12-24 01:02:11 UTC
Thanks Jonathan, but I still think you are mistaken in that you don't understand why the function exists in its various forms. Your explanation is technical and not philosophical.

Whether it was originally inherited from the standard C library or was a creature of a C++ WG committee isn't material. And yes, you are being speculative. 

We can discuss another day the history, design choices, and rationale behind how floating point calculations have been done. In any event, we are going around in circles.

But the important thing is that this is thankfully being patched.