Как я могу определить, собираюсь ли я для 64-битной архитектуры в C ++?

StackOverflow https://stackoverflow.com/questions/163058

  •  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);
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top