2009-10-09 3 views
4

ISO 표준 C에서 8,16,32 및 64 비트 고정 길이의 정수 유형에 대한 typedef를 신뢰할 수있는 방법으로 선언 할 수 있습니까? 내가 ISO 표준 C를 말할 때표준 C에서 고정 크기 정수 typedef 선언

, 나는 그 엄격하게 의미 :

  • ISO C89/C90, C99하지합니다.
  • ISO 표준에서 정의되지 않은 헤더가 없습니다.
  • ISO 표준에서 정의되지 않은 전 처리기 기호가 없습니다.
  • ISO 표준에 유형 크기 가정이 지정되어 있지 않습니다.
  • 독점 공급 업체 기호가 없습니다.

다른 질문이 StackOverflow와 비슷하지만 위의 제약 조건 중 하나를 위반하지 않는 답변은 없습니다. 플랫폼 심볼을 사용하지 않고 가능한지 확실하지 않습니다.

+0

이 질문을 빨리 읽는 것은 어렵습니다. 그렇지만이 표준은 1990 년에 발행되었지만 거의 항상 C89라고 불린다. – DigitalRoss

+0

주어진 구현에 8/16/32/64 비트 정수형이 전혀없는 경우 필요한 동작을 지정하십시오. –

답변

8

수 있습니다.

헤더 파일 limits.h은 C90의 일부 여야합니다.그런 다음 전 처리기 지시문 값 SHRT_MAX, INT_MAX, LONG_MAXLLONG_MAX을 테스트하고 이에 따라 typedef를 설정합니다.

예 :

#include <limits.h> 

#if SHRT_MAX == 2147483647 
typedef unsigned short int uint32_t; 
#elif INT_MAX == 2147483647 
typedef unsigned int uint32_t; 
#elif LONG_MAX == 2147483647 
typedef unsigned long uint32_t ; 
#elif LLONG_MAX == 2147483647 
typedef unsigned long long uint32_t; 
#else 
#error "Cannot find 32bit integer." 
#endif 
+0

이것은 각각의 정수 타입이 차지하는 저장 공간 양만을 제공합니다. CHAR_BIT와 함께 사용하더라도 패딩이나 트랩 비트의 가능성 때문에 모든 유형의 값 비트 수를 보장 할 수 없습니다. –

+0

그래서 16 비트 정수가 필요하고'CHAR_BIT'가 10 일 경우 (관련 값 값이'_MAX' 인 경우) 어떻게합니까? –

+3

@Charles : 부호없는 정수 타입 C는 트랩 비트를 보장하지 않습니다. 'char'는 패딩을 보장하지 않습니다. 그러나 분명히 아직 충분하지 않습니다. –

6

엄밀히 말하자면 ISO 9899 : 1999는 ISO 9899 : 1990을 대체하여 현재 ISO 표준 C 언어 사양이 유일합니다.

integer 유형의 정확한 typedef 이름은 1999 버전의 표준에만 도입되었으므로 원하는 것은 1990 년 버전의 표준을 사용하는 것이 불가능합니다.

+0

예, 기술적으로 C99가 현재의 표준이지만 컴파일러 지원은 여전히 ​​남아 있으며 어쨌든 대답하기가 너무 쉬울 것입니다. ;-) – kbluck

+0

사실, inttypes.h를 지원하지 않는 유일한 사람은 현재 Microsoft입니다. 대부분의 플랫폼에는 inttypes.h를, Windows에는 DWORD, QWORD 등의 typedef를 포함하는 것으로 충분합니다. – asveikau

+2

'inttypes.h'는 C90 에서조차 Unixish (잘, POSIX) 헤더입니다. 'stdint.h'는 C99의 일부이며, 더 중요한 것은 C++ TR1과 C++ 0x이므로 적어도 VC++ 2010에서 지원 될 것입니다. –

3

아무 것도 없습니다. 그러나 몇 가지 제한을 가지고 살고 싶다면 최대 32 비트 크기의 개별 정수 변수를 선언 할 수있는 확실한 방법이 있습니다. long 비트 필드를 사용하십시오 (후자는 최소 32 비트 폭으로 보장되며 비트 필드 선언자가 생략 된 경우 비트 필드에서 최대 비트를 변수에 사용할 수 있습니다). 따라서 :

struct { 
    unsigned long foo : 32; 
} bar; 

분명히 그러한 변수에 대한 포인터를 가질 수 없다는 것과 같은 모든 제한이 있습니다. 이것이 실제로 사는 유일한 방법은 over/underflow의 지정된 경계에서 랩 어라운드가 보장되며 서명 된 유형의 경우 오버플로가 정의되지 않으므로 부호없는 유형에 대해서만 보장됩니다.

순수한 C90에서이 작업을 수행 할 수있는 이식성있는 방법은 없습니다. 무엇보다 컴 포넌트 C90 구현에는 심지어 8 비트 정수가 필요하지 않습니다. 예를 들어, sizeof(char) == sizeof(short) == sizeof(int) == 1CHAR_BIT == 16 (즉, 16 비트 기계어가 있고 개별 주소를 사용할 수없는 플랫폼을 갖는 것은 합법적입니다. 바이트). 그러한 플랫폼이 실제로 일부 DSP의 형태로 실제로 존재한다고 들었습니다.

0

아니요, 그렇게 할 수 없습니다.

이제 Gnu configure과 같은 다단계 구성 프로세스를 솔루션으로 계산하려면 C89를 사용하십시오. 그리고 C90에서 이고, 거의 모든 구현에서 DTRT를 사용하므로 원하는 크기를 얻을 수 있고 순응하는 C89를 사용할 수 있습니다. 그러나 비트 너비는 원하는 반면 일반적으로 표준에 의해 지정되지는 않습니다.

0

같은 접근 방식을 가진 위험 현대 컴파일러 컴파일러는 하나 개의 정수 타입의 포인터가 다른 사람의 액세스 값을 사용하지 않을 것이라고 가정하는 것이 유행이되었다이다를 사용하는 경우, 두 유형 모두 같은 크기 및 표기가있는 경우에도입니다. 두 가지 유형이 같은 크기와 표현을 갖고 동일한 프로그램의 두 부분이 각각 하나를 선택하면 이러한 데이터에 대한 포인터를 공유하는 프로그램에 링크 시간 최적화를 적용하면 부적절한 동작이 발생할 수 있습니다. 많은 시스템의 일부 구현에서는 적어도 하나의 크기의 정수가 존재하므로 그 크기의 정수 값을 모두 액세스하는 데 안전하게 사용할 수있는 포인터를 선언 할 수 없습니다. 예 : longlong long이 모두 64 비트 인 시스템에서는 두 유형의 데이터에 액세스 할 때 안정적으로 사용할 수있는 포인터를 선언 할 방법이 없습니다.