Не всё делается одинаково во всех компиляторах, не на всех платформах, приходится временами городить хитрые конструкции из #if/#elif/#endif. Случайно наткнулся на шпаргалку, в которой описано, какие директивы препроцессора предопределяют конкретные компиляторы: http://sourceforge.net/p/predef/wiki/Compilers/
С того же ресурса:
- для операционных систем: http://sourceforge.net/p/predef/wiki/OperatingSystems/
- для стандартов языка:
http://sourceforge.net/p/predef/wiki/Standards/
- более актуальная информация от проекта GCC: https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
- для стандартных библиотек (реализаций) C и C++: http://sourceforge.net/p/predef/wiki/Libraries/
- для архитектур: http://sourceforge.net/p/predef/wiki/Architectures/
А так же определение порядка байтов: http://sourceforge.net/p/predef/wiki/Endianness/
Другие ссылки на эту тематику:
Ниже самое нужное мне, тезисно.
Версии C++ и его библиотек
199711L- C++98201103L- C++11201402L- C++14201703L- C++17202002L- C++20202302L- C++23
Можно проверять отдельные фичи (начиная с C++20):
Платформы Windows/Linux/Android
- Linux:
__linux__
- Windows (TBD: перепроверить`):
_WIN16- скорее всего не встретится, для 16 бит окружения_WIN32- определено для 32 и для 64 бит окружения_WIN64- определено для 64 бит окружения
- Android
- на нём же определён
__linux__ __ANDROID____ANDROID_API__- значение - API level (<android/api-level.h>)
- на нём же определён
Архитектура x86/x86_64/arm/aarch64
- x86_64
__amd64____x86_64__
- x86
- GCC/Clang:
__i386__- и куча вариаций (при этом предыдущий так же будет определён)
__i486____i586____i686__
- и куча вариаций (при этом предыдущий так же будет определён)
- MinGW:
_X86_
- Visual Studio:
_M_I86- только для 16 бит платформ_M_IX86- только для 32 бит платформ, при этом это и версия типаV00(300 - 386, 400 - 486, 500 - 586, 600 - 686)
- GCC/Clang:
- arm64/aarch64
__aarch64__, но__arm__тоже определён
- arm
__arm____thumb__- ещё куча всего связанного с конкретными архитектурами
Компиляторы
- Clang
__clang__- стоит отметить, что в IDE использующих llvm/clang для парсинга (Qt Creator) этот макрос будет определён в дополнении к макросам реального компилятора.__clang_major____clang_minor____clang_patchlevel____clang_version__
- GCC
__GNUC__- он же major версии компилятора__GNUC_MINOR____GNUC_PATCHLEVEL__- может быть не определён__GNUC_VERSION__- децимальная версия (__GNUC__ * 10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
- MSVC
_MSC_VER- децимальная версия, видаVVRR:VV- Version,RR- Revision- наиболее актуальные:
1900- 14.0 (2015)1910..1916- 15.0 (2017)..15.9 (2017)1920..1929- 16.0 (2019)..16.11 (2019)1930..1944- 17.0 (2022)..17.14 (2022)
- наиболее актуальные:
_MSC_FULL_VER- полная децимальная версия видаVVRRPPPP:VV- Version,RR- Revision,PPPP- Patch, начиная с Visual C++ 6.0 Processor packVVRRPPPPP:VV- Version,RR- Revision,PPPPP- Patch, начиная с Visual C++ 8.0 (больше цифр для Patch)
- Детально тут: Microsoft C++ (MSVC) compiler versioning
- MinGW
__MINGW32____MINGW64__
Big/Little Endianness
- BE
__BIG_ENDIAN____BYTE_ORDER__ = __BIG_ENDIAN____FLOAT_WORD_ORDER__ == __BIG_ENDIAN__
- LE
__LITTLE_ENDIAN____BYTE_ORDER__ = __LITTLE_ENDIAN____FLOAT_WORD_ORDER__ = __LITTLE_ENDIAN__
На C++20 в compile-time можно проверять через std::endian.