It appears that as of 6.0.0, /usr/include/c++/6.0.0/cmath does:
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <math.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
which appears to have the effect of forcing it to include /usr/include/math.h instead of the math.h from gnulib, which I expect is how gnulib worked with C++ before. This appears to be done now for all of the C++ C library header wrappers, e.g. cstdlib:
// Need to ensure this finds the C library's <stdlib.h> not a libstdc++ // wrapper that might already be installed later in the include search path. #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <stdlib.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
This is currently causing lots of trouble for octave by effectively disabling gnulib. Since octave uses the GNULIB_NAMESPACE of "gnulib", it is using things like "gnulib::floor", but since the gnulib math.h is no longer included there is no gnulib::floor declared.
I seem to be able to work around it at the moment by explicitly including <math.h> before <cmath>, although I still haven't managed to get octave to compile yet. But I expect a better solution will need to be found for a permanent fix.
On 19/02/16 16:33 -0700, Orion Poplawski wrote:
It appears that as of 6.0.0, /usr/include/c++/6.0.0/cmath does:
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <math.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
which appears to have the effect of forcing it to include /usr/include/math.h
It has the effect of skipping the first <math.h> that gets found, so that we don't end up in a loop. The purpose of that is to find the libc <math.h> rather than the libstdc++ one, so typically /usr/include/math.h, yes.
instead of the math.h from gnulib, which I expect is how gnulib worked with C++ before. This appears to be done now for all of the C++ C library header wrappers, e.g. cstdlib:
No, only for <math.h> and <stdlib.h>.
This is currently causing lots of trouble for octave by effectively disabling gnulib. Since octave uses the GNULIB_NAMESPACE of "gnulib", it is using things like "gnulib::floor", but since the gnulib math.h is no longer included there is no gnulib::floor declared.
<math.h> is a standard header, putting another header with that name in the include path is undefined behaviour.
If gnulib wants to play at being the standard library it needs to do so correctly, to be compatible with whatever standard library is it pretending to be, as documented at https://gcc.gnu.org/gcc-6/porting_to.html (which would probably mean the path to the gnulib headers needs to be specified with -isystem not -I so that it comes after the libstdc++ <math.h> not before it).
If gnulib is not trying to be <math.h> but is just borrowing the name then it needs to change the name to avoid undefined behaviour.
I seem to be able to work around it at the moment by explicitly including <math.h> before <cmath>, although I still haven't managed to get octave to compile yet. But I expect a better solution will need to be found for a permanent fix.
I'll look into it and see what gnulib is playing at.
On 19/02/16 23:45 +0000, Jonathan Wakely wrote:
If gnulib wants to play at being the standard library it needs to do so correctly, to be compatible with whatever standard library is it pretending to be, as documented at https://gcc.gnu.org/gcc-6/porting_to.html (which would probably mean the path to the gnulib headers needs to be specified with -isystem not -I so that it comes after the libstdc++ <math.h> not before it).
And also using the _GLIBCXX_INCLUDE_NEXT_C_HEADERS trick to forward on to libc <math.h>
If gnulib is not trying to be <math.h> but is just borrowing the name then it needs to change the name to avoid undefined behaviour.
This seems more likely, if it's defining gnulib::floor and not std::floor.
On 19/02/16 16:33 -0700, Orion Poplawski wrote:
I seem to be able to work around it at the moment by explicitly including <math.h> before <cmath>,
That might actually be a reasonable fix.
There is no guarantee whatsoever that <cmath> includes <math.h>, so it is not portable and not guaranteed to work when Octave assumes that including <cmath> will indirectly include gnulib's <math.h>.
If Octave wants to include gnulib's <math.h> then it should be including it itself, not relying on some other header doing so indirectly.
Furthermore, when GCC's <cmath> wants to include <math.h> it *really* does want libc's <math.h>, which is what GCC was configured against, and what it expects to find again when you compile. If some other <math.h> turns up it could break all sorts of things.
Gnulib does seem to be going to some lengths to co-operate with the real <math.h> (using #include_next itself, and putting everything in a namespace when requested to) but it's entirely right that <cmath> gets to decide what it wants to include, Octave should not be interfering with the implementation's headers.
So for Octave to include gnulib's <math.h> either it should have a different name, such as <gl_math.h>, or it should include it as <libgnu/math.h>, or just ensure it is included directly, and not as a side effect of including <cmath>.
The next problem is that gnulib defines:
inline int signbit (float f) { return _gl_cxx_signbitf (f); } inline int signbit (double d) { return _gl_cxx_signbitd (d); } inline int signbit (long double l) { return _gl_cxx_signbitl (l); }
GCC 6 provides a standard-conforming <math.h> which defines the same signbit overloads (as required by C++11 and C++14). So the gnulib header is incompatible with any conforming C++11 implementation.
On 02/19/2016 07:07 PM, Jonathan Wakely wrote:
The next problem is that gnulib defines:
inline int signbit (float f) { return _gl_cxx_signbitf (f); } inline int signbit (double d) { return _gl_cxx_signbitd (d); } inline int signbit (long double l) { return _gl_cxx_signbitl (l); }
GCC 6 provides a standard-conforming <math.h> which defines the same signbit overloads (as required by C++11 and C++14). So the gnulib header is incompatible with any conforming C++11 implementation.
Yeah, I think this has been addressed here:
http://lists.gnu.org/archive/html/bug-gnulib/2016-02/msg00027.html
On 20/02/16 02:07 +0000, Jonathan Wakely wrote:
The next problem is that gnulib defines:
inline int signbit (float f) { return _gl_cxx_signbitf (f); } inline int signbit (double d) { return _gl_cxx_signbitd (d); } inline int signbit (long double l) { return _gl_cxx_signbitl (l); }
GCC 6 provides a standard-conforming <math.h> which defines the same signbit overloads (as required by C++11 and C++14). So the gnulib header is incompatible with any conforming C++11 implementation.
Here's a patch for Octave which hacks around the above problem in gnulib and then fixes Octave to include gnulib headers explicitly, instead of assuming they'll get found by GCC's std::lib.
I haven't waited for octave to finish building (it's after 3am here) but if other files fail just #include <libgnu/math.h> or #include <libgnu/stdlib.h> and it should work.
The gnulib change is a hack, a proper fix would only skip the signbit overloads for __cplusplus >= 201103L, but would also make sure to #undef signbit if there's an earlier #define signbit 1. Maybe that should be done by defining @GNULIB_SIGNBIT@ to something different.
On 02/19/2016 08:24 PM, Jonathan Wakely wrote:
On 20/02/16 02:07 +0000, Jonathan Wakely wrote:
The next problem is that gnulib defines:
inline int signbit (float f) { return _gl_cxx_signbitf (f); } inline int signbit (double d) { return _gl_cxx_signbitd (d); } inline int signbit (long double l) { return _gl_cxx_signbitl (l); }
GCC 6 provides a standard-conforming <math.h> which defines the same signbit overloads (as required by C++11 and C++14). So the gnulib header is incompatible with any conforming C++11 implementation.
Here's a patch for Octave which hacks around the above problem in gnulib and then fixes Octave to include gnulib headers explicitly, instead of assuming they'll get found by GCC's std::lib.
I haven't waited for octave to finish building (it's after 3am here) but if other files fail just #include <libgnu/math.h> or #include <libgnu/stdlib.h> and it should work.
The gnulib change is a hack, a proper fix would only skip the signbit overloads for __cplusplus >= 201103L, but would also make sure to #undef signbit if there's an earlier #define signbit 1. Maybe that should be done by defining @GNULIB_SIGNBIT@ to something different.
Jonathan - Thank you for all your help with this.
On 20/02/16 08:36 -0700, Orion Poplawski wrote:
On 02/19/2016 08:24 PM, Jonathan Wakely wrote:
On 20/02/16 02:07 +0000, Jonathan Wakely wrote:
The next problem is that gnulib defines:
inline int signbit (float f) { return _gl_cxx_signbitf (f); } inline int signbit (double d) { return _gl_cxx_signbitd (d); } inline int signbit (long double l) { return _gl_cxx_signbitl (l); }
GCC 6 provides a standard-conforming <math.h> which defines the same signbit overloads (as required by C++11 and C++14). So the gnulib header is incompatible with any conforming C++11 implementation.
Here's a patch for Octave which hacks around the above problem in gnulib and then fixes Octave to include gnulib headers explicitly, instead of assuming they'll get found by GCC's std::lib.
I haven't waited for octave to finish building (it's after 3am here) but if other files fail just #include <libgnu/math.h> or #include <libgnu/stdlib.h> and it should work.
The gnulib change is a hack, a proper fix would only skip the signbit overloads for __cplusplus >= 201103L, but would also make sure to #undef signbit if there's an earlier #define signbit 1. Maybe that should be done by defining @GNULIB_SIGNBIT@ to something different.
Jonathan - Thank you for all your help with this.
No problem. I knew my changes to make GCC's <math.h> and <stdlib.h> more strictly conforming would cause some problems, because the bugs I fixed had been there for years and years. It was inevitable that some packages would have local workarounds for the bugs, which would need to be removed once the GCC headers got fixed.