Opened 10 years ago
Closed 4 years ago
#7473 closed Bugs (obsolete)
clang defines __GNUC__ and confuses the libstdcpp3.hpp configuration header
Reported by: | Owned by: | John Maddock | |
---|---|---|---|
Milestone: | To Be Determined | Component: | config |
Version: | Boost 1.56.0 | Severity: | Problem |
Keywords: | Cc: |
Description
clang defines (at least on the current trunk) GNUC, GNUC_MINOR, and GNUC_PATCHLEVEL to 4, 2, and 1 respectively. When used with -std=c++11 GXX_EXPERIMENTAL_CXX0X will be defined as well. When using libstdcpp in combination with clang the boost configuration header libstdcpp3.hpp will use those broken version to detect library headers and features. Given the relatively low version number, most headers wont be available, which is counter-intuitive and can break in subtle ways.
Change History (18)
comment:1 by , 10 years ago
follow-up: 4 comment:2 by , 10 years ago
Clang can work with more recent versions of libstdc++ than gcc-4.2's libstdc++ (though sometimes patches are needed). With those stdlib, we can use C++11 features.
What is needed here is to use __GLIBCXX__
to detect the version of libstdc++.
comment:4 by , 10 years ago
Replying to michel:
Clang can work with more recent versions of libstdc++ than gcc-4.2's libstdc++ (though sometimes patches are needed). With those stdlib, we can use C++11 features.
What is needed here is to use
__GLIBCXX__
to detect the version of libstdc++.
It seems the mistake is to use the gcc version to detect the version of the library to begin with. However, I cannot find a good reference for the macros that good be used to detect the libstdc++ version besides this page. __GLIBCXX__
doesn't seem particularly helpful unless someone is willing to figure out what those values can be and create a table from them.
comment:5 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
What is needed here is to use
__GLIBCXX__
to detect the version of libstdc++.
That's what we used to do originally. However, it caused a whole bunch of problems and we were specifically advised against doing that by the libstdc++ developers. The issue is that __GLIBCXX__
can have a higher value for say gcc-4.4.x than for gcc-4.5.0 but fewer features. I believe the bug here is in clang (or in the way you're using it). As far as I can see the only reliable way to support non-standard configurations like this is to use the supplied configure script to generate a custom configuration: http://www.boost.org/doc/libs/1_53_0/libs/config/doc/html/index.html#boost_config.configuring_boost_for_your_platform.using_the_configure_script
comment:6 by , 9 years ago
I'm hesitant to reopen because I'm relatively new to boost, but I believe this is still a big issue, and will become even more annoying in the future if nothing is done. It is frustrating that it is such a hurdle to use modern features of the most important C++ library with a modern mature wide spread C++ compiler.
Bumping __GNUC_MINOR__
has been discussed and discarded by clang-dev
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021510.html
So what about an additional check using __clang_major__
and __clang_minor__
? This seems only consistent if you choose (for good reason) not to use __GLIBCXX__
. Blaming this to be a bug in clang doesn't really help anyone either.
P.S.:
Even Jonathan Wakely advises against using __GXX_EXPERIMENTAL_CXX0X__
comment:7 by , 9 years ago
Another suggestion: the availabilty of C++11 features may also (should) be tested by checking _ _cplusplus http://gcc.gnu.org/ml/gcc-help/2011-05/msg00355.html
This macro is defined in the C++ Standard and independent of the specific compiler, be it GCC or Clang.
GCC 4.7 is cheating, however, they set _ _cplusplus to 201103L, but haven't fully implemented the new features. This happened in GCC 4.8.1 only: http://gcc.gnu.org/gcc-4.8/cxx0x_status.html
comment:8 by , 9 years ago
The issue here is that the compiler and std lib are out of synch with each other. Testing the clang or std version doesn't help if the library was actually shipped for an older compiler version as is the case here.
I repeat - what's wrong with using the supplied configure script to fix unsupported configurations like this? See http://www.boost.org/doc/libs/1_53_0/libs/config/doc/html/index.html#boost_config.configuring_boost_for_your_platform.using_the_configure_script
comment:9 by , 9 years ago
IMHO, the problem is that this configuration (clang + gcc stdlibc++) is not that uncommon on linux and usually work quite well together. libc++ seems not to be in that good shape (for linux) and it's quite a hassle installing it.
The problem with user-defined configurations is that if you are writing a library that uses boost, every user of that library will have to configure boost by himself..
comment:10 by , 9 years ago
Here's the thing: I'm quite happy to apply a fix for this, but I just don't see how it can possibly be made to work. To recap:
__GLIBCXX__
is useless for this purpose as it reflect release date, not lib version.__clang_major__
tells us nothing about the std lib, only about Clang itself.__cplusplus
tells us nothing about the std lib, only Clang itself.- I can't see any internal libstdc++ macros can can be used for this purpose.
- There's no way to tell whether the necessary patches (some official some not) have been applied to libstdc++, to pick one example recent versions of <type_traits> don't compile with
clang -std=gnu++11
because clang lacks___float128
. It's trivial to patch, but there's no official clang patch last time I looked. - Clang only claims to be compatible with GCC-4.2.1, frankly anything else is unsupported as far as I can see... even though use with later versions is very useful and what most of us actually do!
Finally, if the user has to patch libstdc++, why not patch/configure boost as well? At least Intel's compiler sets the GCC version number to match that of the underlying std lib which avoids all this nonsense.
So... I don't see any way to fix this unless someone submits a patch that "works" and avoids the above pitfalls. The only thing I could think of, would be to use __GLIBCXX__
to detect libstdc++ features only when the compiler is clang. That would work some of the time, but break boost completely some of the time too, which frankly is not a path I want to take.
comment:11 by , 9 years ago
Thank you johnmaddock for the detailed and rational description. I do have a few remarks though:
- Is clangs compatibility with gcc really relevant here? Shoudln't the C++11 compatibility be primary here?
- Yes clang -std=gnu++11 is broken
Simply trying to compile the following with clang++ -std=gnu++11 fails for me due to said lack of __float128
:
#include <boost/functional/hash.hpp>
(Boost 1.53.0, clang 3.2.6, libstdc++ of gcc 4.8.0 on arch). IMHO it looks to me that clang (with gnu++11 and libstd++) is broken and should be fixed (since it doesn't allow me to include <utility>). Or would you consider that a case of boost being completely broken?
- So what about allowing all the nice features if all of the following holds:
- Compiler is clang
__GLIBCXX__
is reasonably new: Pick a date where it is safe to assume that all later releases support the features plus maybe a list of release dates of versions known to support the features.__cplusplus
is C++11__STRICT_ANSI__
is defined indicating that it's not gnu++11.
comment:12 by , 8 years ago
I just tripped over this head-scratcher (why can't I construct a shared_ptr from a unique_ptr?!).
For what it's worth, I've tried a quick hack commenting out all ACTIV_BOOST_NO_CXX11_* macros in libstdcpp3.hpp for 4.3-4.7 GCC when building with clang 3.4 and libstdc++ 4.8.3.
Boost 1.56 with std=c++11 builds successfully, as do all the tests (except 1 that happens with a plain g++ 4.8.3 c++11 build, too).
Doesn't help with the GLIBCXX problem, I'm just pointing out that no patches had to be applied (unless Fedora themselves do so, I suppose).
Regards
Luke Elliott.
comment:13 by , 8 years ago
Update: I looked at this again with a view to making cautious use of __GLIBCXX__
when the compiler is clang, but __GLIBCXX__
versions are so scrambled up as to be functionally useless, for example looking at https://www.gnu.org/software/gcc/releases.html I see
libstdc++ 4.3.5 later than 4.5 libstdc++ 4.3.6 later than 4.6 libstdc++ 4.5.4 later than 4.7 libstdc++ 4.6.4 later than 4.8 libstdc++ 4.7.4 later than 4.9
And that's just the obvious ones, and doesn't include "unofficial" releases from Apple etc.
Back to square 1...
comment:14 by , 8 years ago
There's a tentative patch for this issue here: https://github.com/boostorg/config/commit/b36566fe04a89103b7ef5569c03e3a26eb77af36
Replacement header for testing with here: https://raw.githubusercontent.com/boostorg/config/b36566fe04a89103b7ef5569c03e3a26eb77af36/include/boost/config/stdlib/libstdcpp3.hpp
I'd be grateful if as many folks as possible can test this and report back, thanks!
comment:15 by , 8 years ago
Sorry for missing this PR, as it was closed a search didn't show it. For 4.8 I can suggest <debug/array> or <ext/random> or <ext/cmath>. For 4.9, maybe <shared_mutex> or <bits/c++14_warning.h>, or <experimental/optional> or <experimental/string_view>. For 5, <experimental/any> for now, maybe something with filesystem soon.
comment:16 by , 7 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Version: | Boost 1.51.0 → Boost 1.56.0 |
Problem is still present at least in 1.56
comment:18 by , 4 years ago
Resolution: | → obsolete |
---|---|
Status: | reopened → closed |
I guess that you need to link with libc++ with clang as libstdcpp doesn't support c++11 features.
I'm using this