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

В функции C ++ мне нужен компилятор, чтобы выбрать другой блок, если он компилируется для 64-битной архитектуры.

Я знаю способ сделать это для MSVC ++ и g ++, поэтому я опубликую это как ответ. Однако я хотел бы знать, есть ли лучший способ (более элегантный, который будет работать для всех компиляторов / всех 64-битных архитектур). Если нет лучшего способа, какие другие предопределенные макросы мне следует искать, чтобы быть совместимым с другими компиляторами / архитектурами?

Ответы [ 8 ]

21 голосов
/ 22 сентября 2015

Архитектурно-независимый способ обнаружения 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
18 голосов
/ 02 октября 2008

Это работает для MSVC ++ и g ++:

#if defined(_M_X64) || defined(__amd64__)
  // code...
#endif
9 голосов
/ 15 февраля 2009

Почему вы выбираете один блок над другим? Если ваше решение основано на размере указателя, используйте sizeof(void*) == 8. Если ваше решение основано на размере целого числа, используйте sizeof(int) == 8.

Я хочу сказать, что название самой архитектуры редко должно иметь какое-либо значение. Вы проверяете только то, что вам нужно проверить, для целей того, что вы собираетесь делать. Ваш вопрос не очень ясно описывает цель проверки. То, что вы спрашиваете, похоже на попытку установить, установлен ли DirectX, путем запроса версии Windows. В вашем распоряжении более портативные и универсальные инструменты.

7 голосов
/ 02 октября 2008
2 голосов
/ 07 октября 2008
#ifdef _LP64

Работает на обеих платформах

1 голос
/ 02 октября 2008

Если вы компилируете для платформы Windows, вы должны использовать:

#ifdef _WIN64

Компилятор MSVC определяет это как для платформ x64, так и для ia64 (вы не хотите обрезать этот рынок, не так ли?). Я не уверен, что gcc делает то же самое, но так и должно быть, если нет.

Альтернатива

#ifdef WIN64

, который имеет небольшую разницу. WIN64 (без начального подчеркивания) определяется SDK (или конфигурацией сборки). Поскольку это определяется конфигурацией SDK / build, оно должно работать так же хорошо с gcc.

1 голос
/ 02 октября 2008

Вот хороший обзор для Mac OS X:

http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting

0 голосов
/ 14 апреля 2012

Если вы используете 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);
    }
...