Условная компиляция в системных заголовочных файлах

0

Вопрос о том, как условная компиляция в системных заголовочных файлах (например, <sys/types.h>) управляет процессом компиляции, путала меня в течение длительного времени. Например, здесь один общий фрагмент кода typedef в <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 ли макрос __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
Теги:
architecture
conditional-compilation

2 ответа

1
Лучший ответ

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

Обратите внимание, что __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 другое определение в зависимости от того, на каком компьютере он установлен? но как компилятор может узнать особенности машины? Нужно ли нам давать эти функции вручную? Но я не помню, чтобы я делал это, когда устанавливал компилятор gcc на мою машину.
  • 0
    На моих машинах я чаще всего использую GCC. Я могу использовать gcc -m64 для генерации 64-битного объектного кода и gcc -m32 для генерации 32-битного кода, каждый раз запуская один и тот же компилятор. Если я попытаюсь использовать компилятор для Mac OS X на компьютере с Linux, он не запустится, и наоборот, так что да, компилятор знает, на каком типе машины он установлен. Компилятор, построенный как 64-разрядный двоичный файл, также не будет работать на машине, которая поддерживает только 32-разрядные двоичные файлы. Таким образом, вы (человек, запускающий компилятор) управляете параметрами компилятора, хотя компилятор будет иметь значения по умолчанию, которые он использует, если вы не переопределите их.
Показать ещё 2 комментария
1

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

gcc -std = С++ 11 -E -P -v -dD temp.cpp

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

Измените -std = С++ 11 на требуемый стандарт.

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню