Компилятор # определяет для g ++ и cl - PullRequest
2 голосов
/ 10 июля 2009

Я пишу программу, которая является кроссплатформенной. Есть несколько мест, где я должен указать вызов, зависящий от операционной системы.

#ifdef WINDOWS
..do windows only stuff
#endif
#ifdef LINUX
..do linux only stuff    
#endif

Существуют ли какие-либо директивы препроцессора, которые определяются компилятором, поэтому мне не нужно явно определять их при использовании компилятора командной строки. то есть.

cl -DWINDOWS program.cpp

или

g ++ -DLINUX program.cpp

Я понимаю, что мог бы легко написать make-файл или иметь скрипт shell / batch, который будет делать это автоматически. Но я бы предпочел использовать те же, что и компилятор (если они существуют) по умолчанию.

Ответы [ 5 ]

5 голосов
/ 10 июля 2009

Я нашел полный список всех g ++ на этом веб-сайте.

  • #define __HAVE_BUILTIN_SETJMP__ 1
  • #define __unix__ 1
  • #define unix 1
  • #define __i386__ 1
  • #define __SIZE_TYPE__ unsigned int
  • #define __ELF__ 1
  • #define __GNUC_PATCHLEVEL__ 3
  • #define __linux 1
  • #define __unix 1
  • #define __linux__ 1
  • #define __USER_LABEL_PREFIX__
  • #define linux 1
  • #define __STDC_HOSTED__ 1
  • #define __EXCEPTIONS 1
  • #define __GXX_WEAK__ 1
  • #define __WCHAR_TYPE__ long int
  • #define __gnu_linux__ 1
  • #define __WINT_TYPE__ unsigned int
  • #define __GNUC__ 3
  • #define __cplusplus 1
  • #define __DEPRECATED 1
  • #define __GNUG__ 3
  • #define __GXX_ABI_VERSION 102
  • #define i386 1
  • #define __GNUC_MINOR__ 2
  • #define __STDC__ 1
  • #define __PTRDIFF_TYPE__ int
  • #define __tune_i386__ 1
  • #define __REGISTER_PREFIX__
  • #define __NO_INLINE__ 1
  • #define _GNU_SOURCE 1
  • #define __i386 1
  • #define __VERSION__ "3.2.3 20030502 (Red Hat Linux 3.2.3-47.3)"

А в Visual C ++ уже определен Win32 для использования с любой версией Widnows.

3 голосов
/ 10 июля 2009

Да, есть такие предопределенные символы, но я не рекомендую вам использовать их, если вы никогда и никогда не предвидите поддержку большего количества платформ, компиляторов или версий операционной системы. Вот логика.

Во-первых, вам лучше иметь собственный минимальный набор определенных констант компиляции для использования в вашем коде. Потому что вы можете начать с таких вещей:

#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" и покончите с этим.

Конечно, все это сводится к минимуму, если вы используете наиболее часто доступные функции и функции в вашем коде.

2 голосов
/ 10 июля 2009

Все эти ответы были очень хорошими. Решение, которое сработало для меня, было следующим.

#ifdef _WIN32

#endif

#ifdef linux

#endif

WIN32 не был определен cl, но _WIN32 был. linux был определен g ++.

0 голосов
/ 30 июня 2010

Вместо двух макросов для конкретных платформ у вас может быть код в блоке #ifndef #else. Например:

#ifndef _WIN32
// linux specific code
#else
// windows specific code
#endif

При таком решении блок ifndef-else гарантирует, что вы случайно не добавите код между двумя блоками #ifdef (которые предположительно обрабатывают поток выполнения программы таким же образом).

Приведенный выше код также даст вам независимость от компиляции этого кода не только для Linux, но и для любой платформы Unix, при условии, что он поддерживает вызов, без изменения метки макроса с linux на Unix * 1009. * или что-то еще.

0 голосов
/ 10 июля 2009

Да. Я верю, что WIN32 есть, но я сейчас не на Windows, чтобы проверить его: D

См: http://en.wikipedia.org/wiki/C_preprocessor (упоминается WIN32)

...