programing

C에서 64비트 컴파일을 검색하는 중

yellowcard 2023. 6. 19. 21:22
반응형

C에서 64비트 컴파일을 검색하는 중

C 매크로 또는 C에서 컴파일할 때 C 프로그램이 64비트 또는 32비트로 컴파일되었는지 확인할 수 있는 방법이 있습니까?

컴파일러: 확인해야 하는 GCC 운영 체제: 유닉스/리눅스

또한 OS가 64비트를 지원하는지 프로그램을 실행할 때 어떻게 확인할 수 있습니까?

이 "gcc"에 태그를 달았으니, 시도해 보십시오.

#if __x86_64__
/* 64-bit */
#endif

다음은 x86 또는 다른 어떤 것도 가정하지 않는 정확한 휴대용 테스트입니다.

#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
#else
/* wtf */
#endif

컴파일러 및 플랫폼 중립 솔루션은 다음과 같습니다.

// 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

하나 이상의 밑줄로 시작하는 매크로를 피합니다.표준이 아니므로 컴파일러/플랫폼에 없을 수 있습니다.

언어 변호사를 짜증나게 할 쉬운 것.

if(sizeof (void *) * CHARBIT == 64) {
...
}
else {
...
}

상수 식이므로 최적화된 컴파일러는 테스트를 중지하고 실행 파일에 올바른 코드만 넣습니다.

컴파일러별 매크로를 사용합니다.

어떤 아키텍처를 대상으로 하는지는 모르겠지만, 지정하지 않으셨기 때문에 일반적인 Intel 시스템을 가정하겠습니다. 따라서 Intel x86AMD64 테스트에 관심이 있을 것입니다.

예:

#if defined(__i386__)
// IA-32
#elif defined(__x86_64__)
// AMD64
#else
# error Unsupported architecture
#endif

하지만 저는 이것들을 별도의 헤더에 넣고 컴파일러 중립 매크로를 정의하는 것을 선호합니다.

합니다(GLIBC에서는).inttypes.h):

#if __WORDSIZE == 64

UINTPTR_MAX 값을 사용하여 빌드 유형을 확인합니다.

#include <stdio.h>
#include <limits.h>

#if UINTPTR_MAX == 0xffffffffffffffffULL               
# define BUILD_64   1
#endif

int main(void) {

    #ifdef BUILD_64
    printf("Your Build is 64-bit\n");

    #else
    printf("Your Build is 32-bit\n");

    #endif
    return 0;
}

64비트 컴퓨터, 32비트 컴퓨터, 36비트 컴퓨터 등에서 동일한 프로그램 소스를 컴파일할 수 있으며 컴파일할 수 있어야 합니다.

그래서 출처만 보고 좋은 것이 있다면 어떻게 편찬될지 알 수 없습니다.소스가 그리 좋지 않으면 프로그래머가 소스를 컴파일하는 데 무엇이 사용될 것이라고 가정했는지 추측할 수 있습니다.

당신에 대한 나의 대답은:

불량 프로그램에 대해서만 소스 파일에 필요한 비트 수를 확인하는 방법이 있습니다.

당신은 당신의 프로그램이 얼마나 많은 비트를 위해 컴파일될 것인지에 상관없이 작동하도록 노력해야 합니다.

이 질문은 64비트 포인터에 대한 요구 사항인지 64비트 네이티브 정수 산술에 대한 요구 사항인지 또는 둘 다에 대한 요구 사항인지 지정하지 않기 때문에 모호합니다.

일부 다른 답변에서는 64비트 포인터를 탐지하는 방법을 알려주었습니다.질문에 문자 그대로 "컴파일된 주소"가 명시되어 있지만 64비트 주소 공간을 사용할 수 있다는 보장은 없습니다.

대부분의 시스템에서 64비트 포인터를 탐지하는 것은 64비트 산술이 에뮬레이트되지 않는다는 것을 탐지하는 것과 동일하지만 모든 잠재적 시나리오에 대해 보장되는 것은 아닙니다.예를 들어 Emscripten은 최대 크기가 2-1인32 Javascript 배열을 사용하여 메모리를 에뮬레이트하지만 64비트를 대상으로 하는 C/C++ 코드를 컴파일하기 위한 호환성을 제공합니다. Emscripten은 한계에 대해 불가지론자라고 생각합니다(테스트하지는 않았지만).반면, Emscripten은 컴파일러에 의해 명시된 제한에 상관없이 항상 32비트 산술을 사용합니다.그래서 Emscripten은 64비트를 대상으로 한 LLVM 바이트 코드를 사용할 것으로 보입니다.int64비트 포인터를 사용하여 Javascript의 능력을 최대한 활용할 수 있습니다.

저는 원래 다음과 같이 64비트 "네이티브" 정수를 탐지할 것을 제안했지만 패트릭 슐뤼터가 지적했듯이, 이것은 ILP64의 드문 경우만 탐지합니다.

#include <stdint.h>
#if UINT_MAX >= 0xffffffffffffffff
// 64-bit "native" integers
#endif

따라서 정답은 일반적으로 컴파일러가 보고하는 제한 값을 기반으로 모호한 "64비트" 분류의 주소 공간이나 산술 효율성에 대해 어떠한 가정도 해서는 안 된다는 것입니다.컴파일러는 특정 데이터 모델 또는 마이크로프로세서 아키텍처에 대해 이식 불가능한 전처리기 플래그를 지원할 수 있지만, 질문 대상 GCC와 Emscripten 시나리오(Clang이 GCC를 에뮬레이트하는 경우)를 고려할 때 이들조차도 오해의 소지가 있을 수 있습니다(테스트하지는 않았지만).

일반적으로 이러한 시나리오 중 어떤 것도 64비트 주소 공간 및 에뮬레이션되지 않은 64비트 산술을 사용할 수 있는지에 대한 신뢰할 수 있는 표시를 제공할 수 없으므로, 불가지론적이지 않은 빌드 시스템의 맥락을 제외하고는 기본적으로 쓸모가 없습니다(해당 속성에 대한 w.r.t.).따라서 해당 속성의 경우 빌드 시스템이 컴파일할 변형을 선택할 수 있도록 빌드 매크로를 설정하는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/5272825/detecting-64bit-compile-in-c

반응형