내 이해에 따르면, int
처음에는 크기가 16 비트 이상이어야한다는 추가 보장이있는 "기본"정수 유형이어야했습니다. 그 당시에는 "합리적인"크기로 간주되었습니다.
32 비트 플랫폼이 일반화되었을 때 "합리적인"크기가 32 비트로 변경되었다고 말할 수 있습니다.
- 최신 Windows는
int
모든 플랫폼에서 32 비트 를 사용 합니다.
- POSIX
int
는 최소 32 비트를 보장합니다 .
- C #, Java에는
int
정확히 32 비트가 보장되는 유형 이 있습니다.
그러나 64 비트 플랫폼이 표준이되었을 때 아무도 int
다음과 같은 이유로 64 비트 정수로 확장되지 않았습니다 .
- 이식성 : 많은 코드
int
가 32 비트 크기 에 달려 있습니다.
- 메모리 소비 :
int
대부분의 경우 사용중인 숫자가 20 억보다 훨씬 적기 때문에 모든 경우에 대해 메모리 사용량을 두 배로 늘리는 것은 대부분의 경우 비합리적 일 수 있습니다.
이제, 당신은 왜 선호 uint32_t
에 uint_fast32_t
? 같은 이유로 C #과 Java는 항상 고정 크기 정수를 사용합니다. 프로그래머는 다른 유형의 가능한 크기에 대해 생각하는 코드를 작성하지 않고 하나의 플랫폼에 대해 작성하고 해당 플랫폼에서 코드를 테스트합니다. 대부분의 코드는 특정 크기의 데이터 유형에 암시 적으로 의존합니다. 그리고 이것이 uint32_t
대부분의 경우에 더 나은 선택 인 이유 입니다. 동작에 대한 모호성을 허용하지 않습니다.
또한 uint_fast32_t
크기가 32 비트 이상인 플랫폼에서 실제로 가장 빠른 유형입니까? 별로. Windows에서 x86_64 용 GCC의 다음 코드 컴파일러를 고려하십시오.
extern uint64_t get(void);
uint64_t sum(uint64_t value)
{
return value + get();
}
생성 된 어셈블리는 다음과 같습니다.
push
sub $0x20,
mov
callq d <sum+0xd>
add
add $0x20,
pop
retq
이제 get()
의 반환 값을 uint_fast32_t
(Windows x86_64에서 4 바이트)로 변경하면 다음과 같은 결과가 나타납니다.
push %rbx
sub $0x20,%rsp
mov %rcx,%rbx
callq d <sum+0xd>
mov %eax,%eax ; <-- additional instruction
add %rbx,%rax
add $0x20,%rsp
pop %rbx
retq
생성 된 코드는 mov %eax,%eax
32 비트 값을 64 비트 값으로 확장하는 함수 호출 후 추가 명령을 제외하고는 거의 동일 합니다.
32 비트 값만 사용하는 경우에는 이러한 문제가 없지만 size_t
변수 (배열 크기)와 함께 사용 하고 x86_64에서 64 비트 값을 사용하게 될 것입니다 . Linux uint_fast32_t
에서는 8 바이트이므로 상황이 다릅니다.
많은 프로그래머가 int
작은 값을 반환해야 할 때 사용 합니다 ([-32,32] 범위에 있다고 가정 해 봅시다). 이는 int
플랫폼 네이티브 정수 크기 인 경우 완벽하게 작동 하지만 64 비트 플랫폼이 아니기 때문에 플랫폼 네이티브 형식과 일치하는 다른 형식이 더 나은 선택입니다 (작은 크기의 다른 정수와 자주 사용되지 않는 한).
기본적으로 표준이 말하는 것과 상관없이 uint_fast32_t
어쨌든 일부 구현에서는 깨집니다. 일부 위치에서 생성 된 추가 명령어에 관심이 있다면 고유 한 "네이티브"정수 유형을 정의해야합니다. 또는 size_t
일반적으로 native
크기 와 일치하므로이 목적으로 사용할 수 있습니다 (8086과 같은 오래되고 모호한 플랫폼은 포함하지 않고 Windows, Linux 등을 실행할 수있는 플랫폼 만 포함).
int
기본 정수 유형이어야하는 또 다른 기호 는 "정수 승격 규칙"입니다. 대부분의 CPU는 네이티브에서만 작업을 수행 할 수 있으므로 32 비트 CPU는 일반적으로 32 비트 더하기, 빼기 등 만 수행 할 수 있습니다 (인텔 CPU는 여기에서 예외 임). 다른 크기의 정수 유형은로드 및 저장 명령어를 통해서만 지원됩니다. 예를 들어, 8 비트 값은 적절한 "부호화 된 8 비트로드"또는 "부호없는 8 비트로드"명령어를 사용하여로드해야하며로드 후 값을 32 비트로 확장합니다. 정수 승격 규칙이 없으면 C 컴파일러는 원시 유형보다 작은 유형을 사용하는 표현식에 대해 약간 더 많은 코드를 추가해야합니다. 불행히도 64 비트 아키텍처에서는 더 이상 컴파일러가 일부 경우 (위에 표시된대로) 추가 명령을 내 보내야하기 때문에 더 이상 적용되지 않습니다.