Насколько я понимаю, лучшая практика:
#if __cplusplus >= 202002L
// code
#endif
Однако это не работает, хотя я компилирую с -std=c++20.
Кроме того, вывод g++ -x c++ -std=c++20 -dM -E - </dev/null | grep __cplusplus:
#define __cplusplus 201709L
Это меня очень смущает, поскольку я предположил, что правильное определение C++17 — 201703L.
Я что-то пропустил?
Я попытался проверить, существует ли поддержка <=>. Поэтому я также могу попробовать сделать:
#if __cplusplus >= __cpp_impl_three_way_comparison && __cplusplus >= __cpp_lib_three_way_comparison
Однако это не работает, как говорят обе эти константы 201907L.
P.S.
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GCC 11 и новее устанавливает его правильно. Кроме того, часто нет смысла проверять версию C++, обычно вас больше волнуют поддерживаемые конкретные функции.
См. этот ответ в дубле: Распечатайте последний стандарт C++, поддерживаемый gcc, который также использует gcc10. Команда gcc -v --help 2>/dev/null | egrep "gnu\+\+[^I]+ISO [^1]", которая в gcc7.5 говорит, дает результат -std=gnu++11 Conform to the ISO 2011 C++ standard with GNU -std=gnu++14 Conform to the ISO 2014 C++ standard with GNU -std=gnu++1z Conform to the ISO 201z(7?) C++ draft standard
Поддержка C++20 начинается с GCC 11. GCC 10 имеет частичную поддержку C++20 и, скорее всего, не устанавливает __cplusplus.
Также см. этот ответ, в котором объясняется, что «статус функций C++ отслеживается с помощью их макросов тестирования функций. cppreference.com любезно их перечисляет».
@RemyLebeau Посмотрите еще один обман, который я добавил.
@user12002570 user12002570 почему ты меня об этом пингуешь?
@RemyLebeau Потому что ты снова открылся?





В версиях 10 и 11 GCC stdcpp встроенный макрос __cplusplus определяется следующим образом.
if (CPP_OPTION (pfile, lang) == CLK_CXX2A
|| CPP_OPTION (pfile, lang) == CLK_GNUCXX2A)
_cpp_define_builtin (pfile, "__cplusplus 201709L");
else if (CPP_OPTION (pfile, lang) == CLK_CXX20
|| CPP_OPTION (pfile, lang) == CLK_GNUCXX20)
_cpp_define_builtin (pfile, "__cplusplus 202002L");
В руководстве GCC 10.5.0 для стандартных предопределенных макросов C++,
В зависимости от выбранного стандарта языка значение макроса равно 199711L для стандарта C++ 1998 года, 201103L для стандарта C++ 2011 года, 201402L для стандарта C++ 2014 года, 201703L для стандарта C++ 2017 года или неопределенного значения, строго большего, чем 201703L для стандарта C++ 2017 года. экспериментальные языки, включенные -std=c++2a и -std=gnu++2a.
В связи с тем, что последняя версия GCC устанавливает __cplusplusunspecified value strictly larger than 202302L for the experimental languages enabled by -std=c++26 and -std=gnu++26, это произвольное значение кажется их рабочим соглашением для экспериментальной поддержки.
Это неправильный способ проверки макроса проверки функций. Вы не сравниваете значение __cplusplus с данным макросом:
#if __cplusplus >= __cpp_impl_three_way_comparison && __cplusplus >= __cpp_lib_three_way_comparison
Вместо этого вы просто проверяете значение самого макроса:
#if __cpp_lib_three_way_comparison >= 201907
Значение для проверки берется из списка макросов проверки функций.
Что , как вы можете видеть , gcc 10.2 определяет 201907 (если вы включите соответствующий заголовок, чтобы можно было выполнить проверку).
В общем, смысла проверять __cplusplus напрямую нет. Он просто недостаточно детализирован — на самом деле он может дать вам только одно возможное значение, и оно никогда не сможет дать вам всю информацию, которую вам нужно знать. Вот почему существуют макросы для проверки функций: у нас есть один макрос для каждой функции, и их можно проверить независимо. Они также, по большей части †, позволяют реализациям принимать функции в произвольном порядке - и это точно отражается в макросах.
† Иногда несколько предложений одновременно касаются определенного макроса проверки функций. Это либо требует реализации всех этих предложений одновременно, либо отправляет некоторые, но не рекламирует их, либо в некоторых случаях мы просто искусственно увеличиваем макрос, чтобы немного упростить реализацию - например. __cpp_lib_format.
Возможно, в GCC 10 отсутствует поддержка C++20, поэтому они не обновили ее, чтобы заявить, что это так? Вы проверили новую версию GCC? Проводник компилятора — хороший ресурс для таких вещей.