Bug 60401 - stdlib.h does not provide abs(long) overload
Summary: stdlib.h does not provide abs(long) overload
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 6.0
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-03 17:06 UTC by Stephan Bergmann
Modified: 2016-01-21 13:02 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-03-04 00:00:00


Attachments
List of errors (1.74 KB, text/plain)
2016-01-20 16:06 UTC, Dominik Vogt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Bergmann 2014-03-03 17:06:31 UTC
When libstdc++ sits on top of glibc, including stdlib.h does not provide an abs(long) overload (unlike including cstdlib providing a std::abs(long) overload).

Similarly for C++11 abs(long long) and stdlib.h vs. cmath abs(float/double/long double).

(Fixing this needs cooperation with glibc, see the mail thread starting at <http://gcc.gnu.org/ml/libstdc++/2014-03/msg00002.html> "stdlib.h abs(long) overload?")
Comment 1 Richard Biener 2014-03-04 11:06:02 UTC
If you include stdlib.h and not cstdlib it's a glibc bug, not a gcc/libstdc++ one.
Comment 2 Jonathan Wakely 2014-03-04 11:16:40 UTC
(In reply to Richard Biener from comment #1)
> If you include stdlib.h and not cstdlib it's a glibc bug, not a
> gcc/libstdc++ one.

Yes, but if glibc fixes it then we'll also need changes in libstdc++ to avoid duplicate definitions, so it needs coordination.

There are a number of issues like this that I want to fix in collaboration with the glibc team, so keeping the bug here is helpful.
Comment 3 Marc Glisse 2014-03-04 13:53:23 UTC
(dup of PR 33935)

(In reply to Richard Biener from comment #1)
> If you include stdlib.h and not cstdlib it's a glibc bug, not a
> gcc/libstdc++ one.

It would make sense for libstdc++ to provide wrappers to the C headers, for all the libc (not just glibc) that only handle C. We already provide complex.h, fenv.h, tgmath.h.

(In reply to Jonathan Wakely from comment #2)
> Yes, but if glibc fixes it then we'll also need changes in libstdc++ to
> avoid duplicate definitions, so it needs coordination.

If they only add the C++03 declarations, they can reuse the same macros as solaris without coordination. And libstdc++ can put in place macros for the new C++11, ready for anyone to use. Of course it is better to make sure those match what glibc is willing to do ;-)
Comment 4 Jonathan Wakely 2016-01-19 21:44:27 UTC
Author: redi
Date: Tue Jan 19 21:43:55 2016
New Revision: 232586

URL: https://gcc.gnu.org/viewcvs?rev=232586&root=gcc&view=rev
Log:
Add C++-conforming wrappers for stdlib.h and math.h

	PR libstdc++/14608
	PR libstdc++/60401
	* include/Makefile.am: Use c_compatibility math.h and stdlib.h for
	--enable-cheaders=c_global configs.
	* include/Makefile.in: Regenerate.
	* include/c_compatibility/math.h: Remove obsolete _GLIBCXX_NAMESPACE_C
	test and allow inclusion from C files.
	* include/c_compatibility/stdlib.h: Likewise. Support freestanding.
	(at_quick_exit, quick_exit): Add using directives.
	* include/c_global/cmath: Use #include_next for math.h.
	* include/c_global/cstdlib: Use #include_next for stdlib.h.
	* testsuite/26_numerics/headers/cmath/14608.cc: New.
	* testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc:
	Remove xfail for most targets.
	* testsuite/26_numerics/headers/cstdlib/60401.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/26_numerics/headers/cmath/14608.cc
      - copied, changed from r232581, trunk/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
    trunk/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/60401.cc
      - copied, changed from r232581, trunk/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/Makefile.am
    trunk/libstdc++-v3/include/Makefile.in
    trunk/libstdc++-v3/include/c_compatibility/math.h
    trunk/libstdc++-v3/include/c_compatibility/stdlib.h
    trunk/libstdc++-v3/include/c_global/cmath
    trunk/libstdc++-v3/include/c_global/cstdlib
    trunk/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c.cc
Comment 5 Jonathan Wakely 2016-01-19 21:47:00 UTC
Fixed on trunk
Comment 6 Dominik Vogt 2016-01-20 16:04:33 UTC
The fix seems to be incomplete.  This program still does not compile:

-- snip --
#include <math.h>
static long double (*p3c_)(long double) = acosh;
-- snip --

  $ g++ -std=c++11 -S x.C
  x.C:3:43: error: invalid conversion from ‘double (*)(double) throw ()’ to ‘long double (*)(long double)’ [-fpermissive]
   static long double (*p3c_)(long double) = acosh;
                                             ^~~~~
  $ g++ --version
  g++ (GCC) 6.0.0 20160120 (experimental)
Comment 7 Dominik Vogt 2016-01-20 16:06:29 UTC
Created attachment 37408 [details]
List of errors

This is a list of all remaining errors of the Plumhall test.  I've not checked whether they all depend on math.h.
Comment 8 Dominik Vogt 2016-01-20 16:11:16 UTC
List of functions the test complains about:

acosh, asinh, atanh, cbrt, copysign, erf, erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb, isinf, isnan, lgamma, llrint, llround, log1p, log2, logb, lrint, lround, nearbyint, nextafter, nexttoward, remainder, remquo, rint, round, scalbln, scalbn, tgamma, trunc
Comment 9 Jonathan Wakely 2016-01-20 16:35:42 UTC
The isnan and isinf errors need a glibc fix, which will be in glibc 2.23, the rest I have a patch for.
Comment 10 Jonathan Wakely 2016-01-20 17:45:30 UTC
Author: redi
Date: Wed Jan 20 17:44:58 2016
New Revision: 232627

URL: https://gcc.gnu.org/viewcvs?rev=232627&root=gcc&view=rev
Log:
Add C++11 <cmath> overloads to the global namespace

	PR libstdc++/60401
	* include/c_compatibility/math.h (acosh, asinh, atanh, acbrt,
	copysign, erf, erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb,
	lgamma, llrint, llround, log1p, log2, logb, lrint, lround, nearbyint,
	nextafter, nexttoward, remainder, remquo, rint, round, scalbln, scalbn,
	tgamma, trunc) [__cplusplus >= 201103L && _GLIBCXX_USE_C99_MATH_TR1]:
	Add using declarations.
	* testsuite/26_numerics/headers/cmath/60401.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/26_numerics/headers/cmath/60401.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/c_compatibility/math.h
Comment 11 Dominik Vogt 2016-01-21 08:16:50 UTC
Looks good, the errors are gone now.  Thanks!
Comment 12 Dominik Vogt 2016-01-21 08:54:19 UTC
Regarding the Glibc fix; do you mean this commit?

  2016-01-11 13:34 Adhemerval Zanella               * Fix isinf/isnan declaration conflict with C++11

That does *not* fix the isnan and isinf errors.
Comment 13 Dominik Vogt 2016-01-21 10:53:13 UTC
I'm running into problems testing the latest Gcc with the latest Glibc.  The test program is just

  #include <math.h>

It's a bit difficult to provide the propert args to g++ to make it use the replacement Glibc after its own headers but before the system Glibc.  This should do it:

  $ g++ --sysroot ~/src/git/glibc/install -std=c++11 x.C

However, this results in errors with isnan and isinf:

-- snip --
  In file included from .../git/gcc/install/include/c++/6.0.0/math.h:36:0,
                   from x.C:1:
  .../gcc/install/include/c++/6.0.0/cmath:614:11: error: ‘::isinf’ has not been declared
     using ::isinf;
             ^~~~~

  .../gcc/install/include/c++/6.0.0/cmath:638:11: error: ‘::isnan’ has not been declared
     using ::isnan;
             ^~~~~
-- snip --

With -v Gcc prints this include dir search list which looks fine to me:

-- snip --
ignoring nonexistent directory ".../glibc/install/usr/local/include"
ignoring nonexistent directory ".../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/../../../../s390x-ibm-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 .../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/../../../../include/c++/6.0.0
 .../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/../../../../include/c++/6.0.0/s390x-ibm-linux-gnu
 .../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/../../../../include/c++/6.0.0/backward
 .../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/include
 .../gcc/install/include
 .../gcc/install/lib/gcc/s390x-ibm-linux-gnu/6.0.0/include-fixed
 .../glibc/install/usr/include
End of search list.
-- snip --

Not sure whether this is a Gcc issue, a Glibc issue or just bad arguments to g++.
Comment 14 Jonathan Wakely 2016-01-21 12:15:52 UTC
(In reply to Dominik Vogt from comment #13)
> -- snip --
>   In file included from .../git/gcc/install/include/c++/6.0.0/math.h:36:0,
>                    from x.C:1:
>   .../gcc/install/include/c++/6.0.0/cmath:614:11: error: ‘::isinf’ has not
> been declared
>      using ::isinf;
>              ^~~~~

If this line is being compiled it means libstdc++ was configured against the old glibc headers (because _GLIBCXX_HAVE_OBSOLETE_ISINF_ISNAN is defined). The error means you are successfully using the new glibc headers when compiling your test, but they don't match the glibc headers used at configure-time.

So I believe the problem is that you need to reconfigure libstdc++ with the new glibc headers, you can't just drop them in later and expect an already-built libstdc++ to work with them. Libstdc++ depends on glibc, so if you update glibc (or fake doing so by using --sysroot to point at a new glibc) then you need to rebuild libstdc++ too.
Comment 15 Jonathan Wakely 2016-01-21 12:24:46 UTC
(In reply to Jonathan Wakely from comment #14)
> So I believe the problem is that you need to reconfigure libstdc++ with the
> new glibc headers, you can't just drop them in later and expect an
> already-built libstdc++ to work with them. Libstdc++ depends on glibc, so if
> you update glibc (or fake doing so by using --sysroot to point at a new
> glibc) then you need to rebuild libstdc++ too.

After discussing this on IRC I'll make a change to support this use case, without needing to rebuild libstdc++ when glibc is updated.
Comment 16 Jonathan Wakely 2016-01-21 13:02:19 UTC
(In reply to Jonathan Wakely from comment #15)
> After discussing this on IRC I'll make a change to support this use case,
> without needing to rebuild libstdc++ when glibc is updated.

I've created https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69413 for that.