Home > front end >  How do I use the __cpp_lib_* feature test macros?
How do I use the __cpp_lib_* feature test macros?

Time:04-23

I wanted to use the feature test macros to check if std::filesystem was available, but __cpp_lib_filesystem isn't defined even when I know std::filesystem is present. For example, the following test program:

#include <iostream>

int main () {

    std::cout << "__cpp_lib_filesystem: "
#ifdef __cpp_lib_filesystem
        << __cpp_lib_filesystem
#else
        << "not defined"
#endif
        << std::endl;

    std::cout << "__has_include(filesystem): "
#ifndef __has_include
        << "don't have __has_include"
#elif __has_include(<filesystem>)
        << "yes"
#else
        << "no"
#endif
        << std::endl;

}

// also, this compiles:
#include <filesystem>
std::filesystem::path test;

Outputs this with gcc 8.1 (my actual target compiler) and gcc 11.2, with --std=c 17:

__cpp_lib_filesystem: not defined
__has_include(filesystem): yes

Here it is on Compiler Explorer.

I also tried including <version>, but, with GCC 8.1, it's not present:

<source>:2:10: fatal error: version: No such file or directory
 #include <version>
          ^~~~~~~~~
compilation terminated.

Additionally, the note here says:

Library feature-test macros - defined in the header <version> (C 20)

Which, unless I'm misinterpreting, means the library feature test macros aren't in <version> until C 20, which doesn't apply to C 17 (although I'm not really clear if it means the header is the C 20 feature, or if the macros are the C 20 feature).

Now, in this particular case, I know I can test for it by doing:

#if defined(__has_include) && __has_include(<filesystem>)
    // ...
#else
    // ...
#endif

That'll work here because filesystem was officially added in C 17 and __has_include has been around since C 17 (or maybe earlier, I dunno) as well -- i.e. there shouldn't be a situation where __has_include isn't available but std::filesystem is. So that's fine.

However, my question is about __cpp_lib_filesystem: Why isn't it defined in the above test? What did I miss / how do I use it?

CodePudding user response:

There are two ways to use the __cpp_lib_XXX macros:

  1. Actually include the corresponding header: https://godbolt.org/z/xo68acnrz

    • And the given library also need to support such feature with the given C version
      • e.g., __cpp_lib_constexpr_vector will not be defined under C 17 even if <vector> was included.
  2. Uses C 20, and include the <version> header.

  • Related