Есть ли стандартный способ определить во время компиляции, является ли система 32 или 64-битной? - PullRequest
7 голосов
/ 15 июля 2011

Мне нужно установить #ifdef - проверка на условную компиляцию.Я хочу автоматизировать процесс, но не могу указать целевую ОС / машину.Есть ли какой-нибудь способ, которым прекомпилятор может решить, работает ли он на 32-разрядной или 64-разрядной версии?

(Пояснение) Мне нужно определить тип, размер которого составляет 64 бита.В 64-битных ОС это длинный, в большинстве других - длинный.

Я нашел этот ответ - это правильный путь?

[править] удобный справочник по макросам компилятора

Ответы [ 8 ]

10 голосов
/ 15 июля 2011

Единственной проверкой компиляции, которую вы можете сделать надежно, будет sizeof(void*) == 8, true для x64 и false для x86.Это constexpr, и вы можете передать его шаблонам, но вы можете забыть использовать ifdef с ним.Не существует независимого от платформы способа узнать размер адреса целевой архитектуры (во время предварительной обработки), вам нужно будет запросить его в IDE.Стандарт даже не имеет понятия размера адреса.

4 голосов
/ 15 июля 2011

В ответ на ваше редактирование существует «бесполезный для вас» способ получить тип, который является 64-битным.

, если вам нужен тип, который может содержать 64 бита, тогда #include <cstdint>и используйте либо int64_t, либо uint64_t.Вы также можете использовать Стандартные целочисленные типы, предоставляемые Boost .

Другой вариант - использовать long long.Технически он не является частью стандарта C ++ (он будет в C ++ 0x), но поддерживается практически на каждом компиляторе.

4 голосов
/ 15 июля 2011

Нет нет поддержки стандартного языка для макроса, чтобы определить, является ли машина 64-битной или 32-битной на этапе препроцессора.

2 голосов
/ 15 июля 2011

Я бы посмотрел исходный код для кроссплатформенной библиотеки. Это довольно большая часть. Каждая пара ОС и компилятор имеет собственный набор определений. Несколько библиотек Вы можете посмотреть:
http://www.libsdl.org/ \include\SDL_config*.h (несколько файлов)
http://qt.nokia.com/ \src\corelib\global\qglobal.h

2 голосов
/ 15 июля 2011

Boost поглотил старый Predef проект.Вам понадобятся макросы архитектуры , точнее BOOST_ARCH_X86_32 / BOOST_ARCH_X86_64, при условии, что вы заботитесь только о x86.

Если вам нужно более широкое обнаружение (например, ARM64), добавьтесоответствующий макрос к вашему чеку, или проверьте то, что вы действительно хотите проверить, например,

sizeof(void*) == 8
1 голос
/ 15 июля 2011

Ну, ответ явно будет зависеть от ОС, поэтому вам нужно сузить свои требования.

Например, в Unix uname -a обычно дает достаточно информации, чтобы отличить 32-разрядную сборку ОС от 64-разрядной.

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

0 голосов
/ 15 июля 2011

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

В вашем Makefile ...

<do stuff to detect and set SUPPORT_XX_BIT to the appropriate value>
gcc myFile.c -D$(SUPPORT_XX_BIT) -o myFile

В вашем коде ...

#if defined(SUPPORT_32_BIT)
...
#elif defined(SUPPORT_64_BIT)
...
#else
    #error "Select either 32 or 64 bit option\n"
#endif
0 голосов
/ 15 июля 2011

Вероятно, самый простой способ - сравнить размеры int и long long. Вы не можете сделать это в препроцессоре, но вы можете использовать его в static_assert.

Редактировать: WoW все отрицательные голоса. Я высказал свою мысль немного яснее. Также, похоже, мне следовало бы упомянуть «длинный длинный», а не «длинный» из-за способа работы MSVC.

...