2014-11-21 2 views
0

Вопроса, как условная компиляция в заголовочных файлах системы (такие как <sys/types.h>) контролируют процесс компиляции смущала меня в течение длительного времени Например, вот фрагмент коды один общие ЬурейеЙ в <sys/types.h>:Условная компиляция в заголовочных файлах система

# if __WORDSIZE == 64 
typedef long int int64_t; 
# elif __GLIBC_HAVE_LONG_LONG 
__extension__ typedef long long int int64_t; 
# endif 
# endif 

Тем не менее, если __WORDSIZE == 64, то мы определим тип int64_t как один псевдоним long int, но мне интересно, что там, где я могу найти определение __WORDSIZE.

  • Был ли макрос __WORDSIZE определен в статическом файле? Если так, как этот файл получить?
  • Или мы передаем макросы препроцессора компилятору?
  • Или компилятор знает, на какой машине он работает точно? Но откуда он это знает?

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

#if the machine is 64-bit 
typedef unsigned long int KEY_TYPE 
#elif the machine is 32-bit 
typedef unsigned long long int KEY_TYPE 
#endif 

ответ

1

Это зависит от компилятора и системы. Он (__WORDSIZE) может быть определен компилятором как встроенный макрос (который может меняться в зависимости от параметров компилятора) или может быть в системном заголовке. Чтение системных заголовков - это тяжелая работа в лучшем случае; в общем, вы не должны пытаться вторгаться в то, что в них.

Обратите внимание, что __WORDSIZE находится в пространстве имен, зарезервированном для реализации. Реализация может делать то, что ему нравится, поскольку она работает правильно. Если вы привяжете свой код к __WORDSIZE, вы можете столкнуться с проблемами при изменении версий компилятора, брендов компилятора, версий операционной системы, брендов операционной системы.

Что касается того, как компилятор определяет, в какой системе он находится: это проблема компилятора. Он создан для генерации кода для конкретной системы (обычно это хост-система, если она не является кросс-компилятором). Компилятор настроен так, чтобы знать, как правильно скомпилировать код; как создать 32-битный объектный код или программы, а также как создать 64-битный объектный код или программы. Это было бы не очень полезно в качестве компилятора, если бы он не знал, как правильно создать код, не так ли?

Вы можете достичь своей цели с:

// #include <stdint.h> // C header 
#include <cstdint>  // C++ analogue of <stdint.h> 

typedef uint64_t KEY_TYPE; 

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

(Оговорка: Технически uint64_t является необязательным типом Однако, похоже, что вы будете иметь проблемы независимо, если он не доступен.).

+0

, который контролирует параметры компилятора? Вы имеете в виду, что компилятор предоставит __WORDSIZE другое определение accordint для того, какой компьютер он установлен? но как компилятор знает об особенностях машины? Нужно ли нам предоставлять этот вариант функции в человеческом плане? Но я не помню, что я это делаю, когда устанавливаю gcc-компилятор на своей машине. –

+0

На моих машинах я чаще всего использую GCC. Я могу использовать 'gcc -m64' для генерации 64-битного объектного кода и' gcc -m32' для генерации 32-битного кода, каждый раз запуская один и тот же компилятор. Если я попытаюсь использовать компилятор для Mac OS X на машине Linux, он не запускается и не наоборот, так что да, компилятор знает, на каком типе машины он установлен. Компилятор, который построен как 64-битный двоичный файл, не будет запускаться на машине, которая поддерживает только 32-разрядные двоичные файлы. Итак, вы (человек, выполняющий компилятор) управляете параметрами компилятора, хотя у компилятора будут значения по умолчанию, которые он использует, если вы не переопределите их. –

+0

Кстати, я также хочу знать взаимосвязь между файлами заголовков системы и файлами заголовков gcc-компилятора. Есть ли взаимозависимость между ними? и кто создает файлы системных заголовков? Выполняет ли процесс установки ОС Linux всегда создание файлов системных заголовков? –

1

Чтобы открыть ССАГПЗ встроенные определяет (до того, как файлы компилируются) можно использовать:

НКА -s = C++ 11 -E -P -v -dd temp.cpp

(temp.cpp просто должна быть пустой файл)

Изменить -std = C++ 11 на стандарт, который вам требуется.

Некоторые из этих встроенных определений будут использоваться для управления компиляцией файлов системных заголовков.

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

Смежные вопросы