다른 아키텍처에서 C의 int 크기
-
05-07-2019 - |
문제
C 언어의 사양이 각 정수 유형의 정확한 크기를 지시하지 않는다는 것을 알고 있습니다 (예 : int
).
내가 궁금해하는 것은 : C (C ++가 아님)에 다른 아키텍처에서 동일하게 될 특정 크기의 정수 유형을 정의하는 방법이 있습니까? 처럼:
typedef int8 <an integer with 8 bits>
typedef int16 <an integer with 16 bits>
또는 프로그램의 다른 부분이 다른 아키텍처에서 컴파일 될 수있는 다른 방법.
해결책
당신이 원하는 것은 <stdint.h>
, C 표준 ( "C99")을 준수하는 컴파일러가 구현됩니다. 불행히도 여기에는 Microsoft가 포함되지 않습니다. 다행히 오픈 소스 프로젝트는 a <stdint.h>
Windows의 경우 참조하십시오 MSINTTYPES.
이것은 당신이 사용할 수있게합니다 int32_t
그리고 uint32_t
, 더하기 8, 16 및 64 및 기타 많은 것들.
참고 : 헤더 파일 자체는 표준에서 선택 사항이 아니지만 헤더의 대부분의 유형은 개별적으로 선택 사항입니다. 일부는 아닙니다. 가장 일반적으로 사용되는 유형은 선택적 유형이지만 필요한 유형은 필요한 유형을 사용하는 것을 막을 수 없습니다. 문제는 구현이 헤더를 전혀 제공하면 실제로 모든 유형을 정의합니다.
다른 팁
C99, in stdint.h,와 같은 유형을 정의합니다 int8_t
그리고 int16_t
.
아니요, C 표준은 적분 유형의 최소 크기를 지정하지만 최대 크기를 보장하지 않습니다.
구현이 제공됩니다 intN_t
유형 해당 크기의 유형을 사용할 수있는 경우. 크로스 플랫폼 태그가 있었기 때문에 올바른 비트 너비 유형이없는 구현은 이러한 유형을 제공 할 필요가 없습니다.
일반적으로 선택할 수 있습니다 (예를 들어, 정의 설정 cc -D_INT16_IS_INT
그리고 #ifdef
s) 특정 비트 크기에 사용할 올바른 유형. C 코드를 사용하여 지원하려는 각 플랫폼에 필요한 정의를 해결할 수 있습니다. CHAR_BIT
그리고 sizeof()
.
C1X Draft (N1362)의 관련 섹션은 다음과 같습니다.
7.18.1.1 정확한 범위 정수 유형
typedef 이름
intN_t
너비의 서명 된 정수 유형을 지정합니다N
, 패딩 비트가없고 2의 보완 표현. 따라서,int8_t
정확히 8 비트의 폭이있는 서명 된 정수 유형을 나타냅니다.typedef 이름
uintN_t
너비의 서명되지 않은 정수 유형을 지정합니다N
. 따라서,uint24_t
정확히 24 비트의 비율로 서명되지 않은 정수 유형을 나타냅니다.이러한 유형은 선택 사항입니다. 그러나 구현이 너비가 8, 16, 32 또는 64 비트 인 정수 유형을 제공하는 경우, 패딩 비트가없고 (서명 된 유형의 경우) 2의 보완 표현이있는 경우 해당 Typedef 이름을 정의해야합니다.
유형의 선택과 관련하여 이와 같은 것이 충분해야합니다.
#ifdef INT32_IS_SHORT
typedef short INT32
#endif
#ifdef INT32_IS_INT
typedef int INT32
#endif
#ifdef INT32_IS_LONG
typedef long INT32
#endif
각 플랫폼을 확인하지 않는 한 #ifdef
또는 쉽게 가능하다고 의심합니다. 그러나 많은 도서관들이 이미 당신을 위해 그 일을하고 있습니다. MSVC의 경우입니다 __int8
, __int16
, &씨. GTK 라이브러리에는 비슷한 typedef가 있습니다.
당신은보고 싶을 수도 있습니다 pstdint.h. STDINT.H의 휴대용 구현이며 C99 컴파일러 지원이 필요하지 않습니다.
내가 아는 한, 대답은 아니오입니다. 우리는 다른 플랫폼을 코딩하고 #if/ #else를 사용하여 특정 플랫폼에 typedefs를 사용합니다. 예를 들어 Win32 : typedef int32;
서명되지 않은 char의 벡터를 사용한 산술 라이브러리를 항상 쓸 수 있습니다. 그렇게하면 원하는 비트 길이의 숫자를 사용할 수 있으며 비트 길이가 다양하게 변할 수도 있습니다.
실제로 GNU MP가 이미 처리하기 때문에 그러한 라이브러리를 구현할 필요는 없습니다.