Да, есть такие предопределенные символы, но я не рекомендую вам использовать их, если вы никогда и никогда не предвидите поддержку большего количества платформ, компиляторов или версий операционной системы. Вот логика.
Во-первых, вам лучше иметь собственный минимальный набор определенных констант компиляции для использования в вашем коде. Потому что вы можете начать с таких вещей:
#if defined(_WIN32)
// do windows stuff
#endif
#if defined(_linux)
// linux stuff
#endif
Предположим, вы разрешаете компиляцию под новым компилятором для окон, которые не определяют _WIN32 автоматически? Вы можете изменить каждую строку _WIN32 на что-то вроде:
#if defined(_WIN32) || defined(ming)
Что является настоящей болью в заднице, если вам нужно изменить более одного из них. Вы могли бы поставить что-то вроде этого на высоком уровне:
#if defined(ming)
#define _WIN32
#endif
Но вы, вероятно, обнаружите, что какой-то системный или библиотечный заголовочный файл выходит из строя, потому что он использует _WIN32. Лучше вы абстрагировали его в общий заголовочный файл:
#if defined(_WIN32) || defined(ming)
#define PLAT_WINDOWS
#endif
А затем просто используйте #ifопределенный (PLAT_WINDOWS), где это необходимо.
Но как насчет этого общего заголовочного файла? Что ж, когда появляется новый компилятор / ОС / что бы то ни было, вы должны начать настраивать его, чтобы убедиться, что он говорит правильные вещи. Довольно скоро это смешной шарик из условия, что можно понять, только если вы знаете о каждой версии каждого компилятора в каждой операционной системе на планете . Ну и дела, кто не делает, но все же любые изменения должны быть проверены везде, и это больно.
Итак, лучше, если у вас есть какой-то высокоуровневый параметр внутри make-файла или даже за его пределами, который говорит "если вы работаете в windows, -DPLAT_WINDOWS" и покончите с этим.
Конечно, все это сводится к минимуму, если вы используете наиболее часто доступные функции и функции в вашем коде.