Как проверить, является ли текущая операционная система Windows, Linux или OSX? - PullRequest
5 голосов
/ 10 октября 2010

Я пишу проект компилятора, который будет производить ассемблерный код в качестве целевого языка. Однако есть некоторые небольшие изменения, которые необходимо учитывать в зависимости от операционной системы, и я не уверен, как проверить ОС. В случае, если это имеет значение, меня интересует только 32 бита. Я видел в некотором исходном коде что-то вроде

#ifdef WIN32

но я понятия не имею, как / если это работает.

РЕДАКТИРОВАТЬ: некоторые уточнения. Я использую gcc на всех трех платформах. Я не знаю, определены ли макросы типа WIN32 через gcc на каждой платформе. Если так, то эти константы, кажется, решают мою проблему.

Ответы [ 3 ]

8 голосов
/ 10 октября 2010

Использование #ifdef использует символы препроцессора для условной компиляции кода в зависимости от того, какие символы определены.В вашем примере компилятор или файл #include может определять WIN32, что означает, что код компилируется в среде Win32.

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

С помощью gcc вы можете отобразить предварительно определенные символы, используя следующую командную строку:

gcc -E -dM - </dev/null

На моей машине один из определенных символов:

#define __FreeBSD__ 8

Это означает, что я использую FreeBSD версии 8.

(Вышеприведенное относится к Cи языки семейства C, такие как C ++.)

3 голосов
/ 10 октября 2010

Обычно основные предопределенные макросы, определяемые платформой, определяются самим компилятором, часто в зависимости от других параметров.

Лучший способ для данного компилятора - поиск «предопределенных макросов» или «предопределенных символов» в их справке. Например: поиск в Google предопределенные макросы Visual Studio выход эта страница .

Мои OOFILE-фреймворки охватывали широкий спектр систем. Файл oofplat.h доступен из Sourceforge svn browser и объединяет различные определения компилятора в _Windows и т. Д.

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

#ifndef _Windows
 #if defined(_WIN32)
  #define _Win32
  #define _Windows
 #elif defined(WIN32)
  #define _Win32
  #define _Windows
 #elif defined(__WIN32__)
  #define _Win32
  #define _Windows
 #elif defined(__Win32__)
  #define _Win32
  #define _Windows
 #elif defined(_WINDOWS)
  #define _Windows
 #elif defined(__INTEL__) && defined(__MWERKS__)
 // Metrowerks CodeWarrior doesn't build anything other than Win32 on INTEL, no DOS
  #define _Windows
  #define _Win32
 #endif
#else
 #if defined __Win32__ || defined _WIN32
  #ifndef _Win32
   #define _Win32
  #endif
 #endif
#endif

#ifndef _MSDOS
 #ifdef _Windows
  #define _MSDOS
 #elif defined(MSDOS)
  #define _MSDOS
 #elif defined(__MSDOS__)
  #define _MSDOS
 #endif
#endif

#ifdef _Windows
 #ifndef STRICT
// some Windows headers define STRICT. In Visual C++ at least having it defined
// affects how static member signatures are mangled, so we define it up front  
  #define STRICT
 #endif
#endif


// if not a DOS machine by now, may be Mac or Unix
// cope with Metrowerks and Symantec (and MPW?)
#ifndef _MSDOS
 #ifndef _Macintosh
  #ifdef macintosh
   #define _Macintosh
  #endif
 #endif
 #ifndef _Macintosh
  #define _Unix
 #endif
#endif
1 голос
/ 10 октября 2010

Это мощность препроцессоров Си. Прежде всего, вы можете определить макросы:

#define MY_MACRO

После этого вы можете проверить, определен ли макрос:

#ifdef MY_MACRO
code, code, code
code, code, code
#endif

Это означает, что код внутри блоков #ifdef и #endif будет действительным, только если этот макрос был определен. Иначе это будет проигнорировано, и с проигнорировано Я имею в виду, что это будет, как будто вы никогда не писали это.

Противоположностью #ifdef является #ifndef. #endif одинаково для обоих случаев.

В вашем случае вы можете использовать макросы для изменения действия функции:

#define MY_MACRO

void my_function() {
#ifdef MY_MACRO
    code_for_my_macro();
#endif
#ifdef ANOTHER_MACRO
    code_for_another_macro();
#endif
}

.. поэтому единственное, что вам нужно сделать для переноса кода, это изменить макрос.

В макросах больше утилит. Ищите «препроцессоры C», и вы увидите все, что вы можете с ними сделать.

...