)" << std::endl; #endif #if defined(__cpp_impl_" /> )" << std::endl; #endif #if defined(__cpp_impl_" /> )" << std::endl; #endif #if defined(__cpp_impl_"/>

Why does the latest clang not define the feature test macro __cpp_coroutines?

121 Views Asked by At
#include <iostream>

int main() {
#if __has_include(<coroutine>)
    std::cout << "__has_include(<coroutine>)" << std::endl;
#endif

#if defined(__cpp_impl_coroutine)
    std::cout << "__cpp_impl_coroutine is defined." << std::endl;
#endif

#if defined(__cpp_coroutines)
    std::cout << "__cpp_coroutines is defined." << std::endl;
#else
    std::cout << "__cpp_coroutines IS NOT defined!" << std::endl;
#endif
}

My compiler is clang-18.1.0.

Build the code with clang++ -std=c++20 -stdlib=libc++ ./main.cpp, and the output is:

__has_include(<coroutine>)
__cpp_impl_coroutine is defined.
__cpp_coroutines IS NOT defined!

Why does the latest clang not define the feature test macro __cpp_coroutines?

2

There are 2 best solutions below

1
Alan Birtles On BEST ANSWER

__cpp_coroutines is an outdated feature test macro, it was split into __cpp_lib_coroutine and __cpp_impl_coroutine before c++20 was standardised. You should use the up to date cpp reference pages for the latest information https://en.cppreference.com/w/cpp/feature_test

Clang seems to have stopped defining __cpp_coroutines since version 17 https://godbolt.org/z/nc1GhGGTo

0
Richard On

I encountered a similar problem where I needed code to compile with:

  • LLVM 15 using C++17 - this works
  • LLVM 15 using C++20 - this works
  • LLVM 17 using C++17 - did not work :-(
  • LLVM 17 using C++20 - this works

I used the following

#include <version> // Needed to pull in __cpp_lib_coroutine (can gate on compiler version if needed)

// This is just to demonstrate whether these feature tests are present at all
#if defined(__cpp_coroutines)
# pragma message("__cpp_coroutines defined")
#endif

#if defined(__cpp_lib_coroutine)
# pragma message("__cpp_lib_coroutine defined")
#endif

// This determines whether coroutines are present and makes a handy cross-compatible compiler flag for it
#if !defined(__clang__)
# error This file should only be used to compile with clang
#else
#if __clang_major__ < 17
    #if defined(__cpp_coroutines)
        #define COROUTINES_PRESENT 1
        #pragma message("Coroutines present clang < 17!") // Just FYI
    #else
        #define COROUTINES_PRESENT 0
        #pragma message("Coroutines absent clang < 17!")  // Just FYI
    #endif
#else
    #if defined(__cpp_lib_coroutine)
        #define COROUTINES_PRESENT 1
        #pragma message("Coroutines present clang >= 17!")  // Just FYI
    #else
        #define COROUTINES_PRESENT 0
        #pragma message("Coroutines absent clang >= 17!")  // Just FYI
    #endif
#endif
#endif

// This is where your code goes
#if COROUTINES_PRESENT
#pragma message("Coroutines present!")
#else
#pragma message("Coroutines absent!")
#endif

int main(){

}

To compile use:

clang++15 main.cpp --std=c++17 -fcoroutines-ts
clang++15 main.cpp --std=c++20
clang++17 main.cpp --std=c++20

From this discussion it looks as though -fcoroutines-ts was deprecated in LLVM 16 so to use coroutines in LLVM 17 you need c++20.