NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: C++ language lawyer Q: requirements for bare abs()?
On Tue, 6 May 2025 at 09:14, Greg Troxel <gdt%lexort.com@localhost> wrote:
>
> I recently had trouble with code in proj, which used abs() from C++,
> expecting it to be double instead of int. Changing to std::abs() fixed
> it.
>
> That brought up the question of what the rules are. In C, abs() is
> solidly integer:
>
> #include <stdlib.h>
>
> int
> abs(int x);
>
> and there is fabs()
>
> #include <math.h>
>
> double
> fabs(double x);
>
> But C++ is different. The standard approach is <cmath> and std::abs(),
> but I find claims that C++11 requires that <cmath> make (bare) abs()
> overloaded, and claims that C++11 permits but does not require it.
The "accepted answer" claims that in C++11+ <cmath> may expose std::abs;.
Looking at your results it seems that LLVM+? did this, but GCC+GLIBCXX
did not (which probably explains why the standard says what it says).
Here NetBSD can hide behind debian.
For <math.h>. The linux's have a the glibc++ with its local copy of
<math.h> that I think, reduces to:
# include <cmath>
use std::abs;
the results show both CLANG+? and GCC+glibc++ agreeing on this quirk.
I suspect NetBSD may be able to argue the moral high ground, but
that's little use.
BTW, the "accepted answer"'s suggestion of using <stdlib.h> and abs()
is just as broken as <math.h>.
> In practice, it seems clear that the only reasonable coding approach is
> to include <cmath> and then use std::abs() but the standards question
> remains.
Agreed.
> I found a test program, enhanced it, and ran it on 5 systems, with
> varying results.
>
> Is NetBSD wrong here? Or is not overloading abs() permissible?
> Is Debian wrong?
How is "none" compiling? Presumably #include <iostream> is up to no
good, see appended.
> c++ -Wall cpp_abs.cpp; ./a.out
>
> none math.h cmath both both/R
> NetBSD/gcc7 1 1 1 1 1
> NetBSD/gcc10 1 1 1 1 1
> Debian/gcc12 1 1.5 1 1.5 1.5
Alpine (musl) and Fedora with newer GCC's match this, see appended.
> macOS 10.13 DNC DNC 1.5 1.5 1.5
clang <= 18? based on appended; also freebsd with clang
> macOS 13 1.5 1.5 1.5 1.5 1.5
clang >18? but could be a a header change
--
Alpine and fedora with much newer GCCs
[root@alpine source]# g++ -Wall -Wextra -Werror abs.cc && ./a.out
abs.cc: In function 'void abses(double, double*, double*)':
abs.cc:21:9: error: 'abs' was not declared in this scope
21 | *ax = abs(x);
| ^~~
abs.cc:22:15: error: 'abs' is not a member of 'std'
22 | *sax = std::abs(x);
| ^~~
[root@alpine source 1]# g++ -Wall -Wextra -Werror abs.cc -DUSE_MATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@alpine source]# g++ -Wall -Wextra -Werror abs.cc -DUSE_CMATH && ./a.out
x=-1.5 ax=1 sax=1.5
[root@alpine source]# g++ -Wall -Wextra -Werror abs.cc
-DUSE_MATH_CMATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@alpine source]# g++ -Wall -Wextra -Werror abs.cc
-DUSE_CMATH_MATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@alpine source]# g++ --version
g++ (Alpine 14.2.0) 14.2.0
cagney@fedora:~$ c++ --version
c++ (GCC) 15.1.1 20250425 (Red Hat 15.1.1-1)
[root@freebsd source]# c++ -Wall -Wextra -Werror abs.cc && ./a.out
abs.cc:21:9: error: use of undeclared identifier 'abs'
21 | *ax = abs(x);
| ^
abs.cc:22:10: error: use of undeclared identifier 'std'
22 | *sax = std::abs(x);
| ^
2 errors generated.
[root@freebsd source 1]# c++ -Wall -Wextra -Werror abs.cc -DUSE_MATH && ./a.out
abs.cc:22:10: error: no member named 'abs' in namespace 'std'; did you
mean simply 'abs'?
22 | *sax = std::abs(x);
| ^~~~~~~~
| abs
/usr/include/c++/v1/stdlib.h:127:64: note: 'abs' declared here
127 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double
abs(long double __lcpp_x) _NOEXCEPT {
| ^
1 error generated.
[root@freebsd source 1]# c++ -Wall -Wextra -Werror abs.cc -DUSE_CMATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@freebsd source]# c++ -Wall -Wextra -Werror abs.cc
-DUSE_MATH_CMATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@freebsd source]# c++ -Wall -Wextra -Werror abs.cc
-DUSE_CMATH_MATH && ./a.out
x=-1.5 ax=1.5 sax=1.5
[root@freebsd source]# c++ --version
FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git
llvmorg-18.1.6-0-g1118c2e05e67)
#ifdef USE_MATH
#include <math.h>
#endif
#ifdef USE_CMATH
#include <cmath>
#endif
#ifdef USE_MATH_CMATH
#include <math.h>
#include <cmath>
#endif
#ifdef USE_CMATH_MATH
#include <cmath>
#include <math.h>
#endif
static void abses(double x, double *ax, double *sax)
{
*ax = abs(x);
*sax = std::abs(x);
}
#include <iostream>
int main(int, const char *[])
{
double x = -1.5;
double ax;
double sax;
abses(x, &ax, &sax);
std::cout << "x=" << x << " ax=" << ax << " sax=" << sax << std::endl;
return 0;
}
Home |
Main Index |
Thread Index |
Old Index