Why does the latest clang not define the feature test macro __cpp_coroutines?
An answer to this question on Stack Overflow.
Question
#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?
Answer
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.