Как я могу определить, собираюсь ли я для 64-битной архитектуры в C ++?
-
03-07-2019 - |
Вопрос
В функции C ++ мне нужно, чтобы компилятор выбирал другой блок, если он компилируется для 64-битной архитектуры.
Я знаю способ сделать это для MSVC ++ и g ++, поэтому я опубликую это как ответ. Однако я хотел бы знать, есть ли лучший способ (более элегантный, который будет работать для всех компиляторов / всех 64-битных архитектур). Если нет лучшего способа, какие другие предопределенные макросы я должен искать, чтобы быть совместимым с другими компиляторами / архитектурами?
Решение
Почему вы выбираете один блок над другим? Если ваше решение основано на размере указателя, используйте sizeof (void *) == 8
. Если ваше решение основано на размере целого числа, используйте sizeof (int) == 8
.
Я хочу сказать, что название самой архитектуры редко должно иметь какое-либо значение. Вы проверяете только то, что вам нужно проверить, для целей того, что вы собираетесь делать. Ваш вопрос не очень ясно описывает цель проверки. То, что вы спрашиваете, похоже на попытку установить, установлен ли DirectX, путем запроса версии Windows. В вашем распоряжении более портативные и универсальные инструменты.
Другие советы
Независимый от архитектуры способ обнаружения 32-битных и 64-битных сборок в C и C ++ выглядит следующим образом:
// C
#include <stdint.h>
// C++
#include <cstdint>
#if INTPTR_MAX == INT64_MAX
// 64-bit
#elif INTPTR_MAX == INT32_MAX
// 32-bit
#else
#error Unknown pointer size or missing size macros!
#endif
Это работает для MSVC ++ и g ++:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
Раймонд покрывает это .
#ifdef _LP64
Работает на обеих платформах
Вот хороший обзор для Mac OS X:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting р>
Если вы компилируете для платформы Windows, вы должны использовать:
#ifdef _WIN64
Компилятор MSVC определяет это как для платформ x64, так и для ia64 (вы не хотите обрезать этот рынок, не так ли?). Я не уверен, что gcc делает то же самое, но так и должно быть, если нет.
Альтернатива
#ifdef WIN64
который имеет небольшую разницу. WIN64 (без начального подчеркивания) определяется SDK (или конфигурацией сборки). Так как это определяется конфигурацией SDK / build, оно должно работать так же хорошо с gcc.
Если вы используете Windows, вам, вероятно, лучше получить " PROCESSOR_ARCHITECTURE " переменная среды из реестра, потому что sizeof (PVOID) будет равен 4, если его 32-битный процесс выполняется в 64-битной операционной системе (также известной как WOW64):
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\CurrentControlSet\\Control\\Session Manager\\Environment"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
LPSTR szArch = new CHAR[100];
ZeroMemory(szArch, 100);
if (RegQueryValueEx(hKey, _T("PROCESSOR_ARCHITECTURE"), NULL, NULL, (LPBYTE)szArch, &dwSize) == ERROR_SUCCESS) {
if (strcmp(szArch, "AMD64") == 0)
this->nArchitecture = 64;
else
this->nArchitecture = 32;
} else {
this->nArchitecture = (sizeof(PVOID) == 4 ? 32 : 64);
}
RegCloseKey(hKey);
}