9

I would like to write a "portable" C++ library in Clang. "Portable" means that I detect (in C preprocessor) what C++ features are available in the compilation environment and use these features or provide my workarounds. This is similar to what Boost libraries are doing.

However, the presence of some features depends not on the language, but on the Standard Library implementation. In particular I am interested in:

  • type traits (which of them are available and with what spelling)
  • if initializer_list being constexpr.

I find this problematic because Clang by default does not use its own Standard Library implementation: it uses libstdc++. While Clang has predefined preprocessor macros __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__, they are hardcoded to values 4, 2, 1 respectively, and they tell me little about the available libstdc++ features.

How can I check in Clang preprocessor what version of libstdc++ it is using?

Andrzej
  • 5,027
  • 27
  • 36
  • so you came to the conclusion that the main factor is the standard library implementation but you want to detect the compiler version ? What's your logic exactly ? `libstdc++` is **distributed** with the **gcc** sources, it's still a different project and there is nothing that makes you think that you are allowed to pinpoint a version of libstdc++ to a particular release of gcc. – user2485710 Feb 07 '14 at 08:24
  • I want to conditionally compile some code (i.e. disable some code by preprocessor directives) if I know that certain things are present in the Standard Library, i.e. in libstdc++. I would like to detect the presence of some things in the library with preprocessor macros, or by other means that will help me detect that. If there are no such means that would also be a good answer for my question. – Andrzej Feb 07 '14 at 08:34
  • @Andrzej I'm not sure how that would work. If your standard library implementation doesn't support a feature or has buggy code, then it will not have that feature or will not work the way you expect it to. You could look up other questions on here that show you how to use a fallback implementation if it doesn't exist in the standard library. –  Feb 07 '14 at 08:52
  • I may not have stated my intent clearly. I am writing a class with @remyabel: 3 member functions: f1, f2, f3. If I know that some standard library feature is broken or non-existent I want my class only to have two functions f1 and f2. I do not want f3 because it would have to use a broken feature. – Andrzej Feb 07 '14 at 09:03
  • @user2485710: Now I got what you were saying. You're right. GCC version was a bad idea, what I should have asked for was libstdc++ version. – Andrzej Feb 07 '14 at 09:40

2 Answers2

3

Clang does come with its own standard library implementation, it's called libc++. You can use it by adding -stdlib=libc++ to your compile command.

That being said, there are various ways to check Clang/libstdc++ C++ support:

  1. Clang has the __has_feature macro (and friends) that can be used to detect language features and language extenstions.
  2. Libstdc++ has its own version macros, see the documentation. You'll need to include a libstdc++ header to get these defined though.
  3. GCC has its version macros which you already discovered, but those would need to be manually compared to the documentation.

And also, this took me 2 minutes of googling.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • 1
    Macro `__GLIBCXX__` - this is what I was looking for. Thanks. – Andrzej Feb 07 '14 at 09:11
  • 2
    As noted in the linked documentation, `__GLIBCXX__` is not a monotonic function of release numbers, 4.4.0 has a way smaller number than 4.3.6, which makes it hard to use to check for a feature. – Marc Glisse Oct 04 '14 at 19:27
  • Boost is updating its detection of the libstdc++ version with clang: https://svn.boost.org/trac/boost/ticket/7473 (it will use __has_include to check for headers that are known to have been added in each version of the library). – Marc Glisse Oct 09 '14 at 08:17
  • 1
    I think using __GLIBCXX__ is not a useful way to discriminate features of libstdc++. For example, I need the trait `std::is_trivially_copy_constructible` which belongs to C++11, but for the longest time gcc has not been shipping with compilers in the 4 version, so, you may use gcc 4.9 something that has the broken traits, and a __GLIBCXX__ higher than a much older version of gcc 5, and therefore smaller __GLIBCXX__ – TheCppZoo Jan 09 '17 at 23:42
2

This is what I think would help. It prints the value of the _LIBCPP_VERSION macro:

#include <iostream>
#include <string>

using namespace std;

int main(int argc, const char * argv[])
{
    cout<<"Value = "<<_LIBCPP_VERSION<<endl;
    return 0;
}

Compile it again the version of clang you want the info for.

user1766438
  • 492
  • 4
  • 13
  • Just a note that you'll have to link to `libc++` on a Linux system by passing `-stdlib=libc++` to `clang++`. – Samuel Li May 18 '21 at 19:49