답변:
size_t
유형의 결과 인 부호없는 정수 타입 sizeof
연산자 (그리고 offsetof
이 시스템이 처리 할 수있는 가장 큰 객체 (예를 들면, 8GB의의 정적 배열)의 크기를 포함하도록 충분히 큰 보장되도록, 연산자).
size_t
유형은보다보다 큰 같거나 작을 수있다 unsigned int
, 당신의 컴파일러 최적화를 위해 그것에 대해 인식 할 수 있습니다.
인터넷에서 pdf 형식으로 제공되는 C99 표준 섹션 7.17, pdf 초안으로 제공되는 C11 표준 섹션 7.19 에서보다 정확한 정보를 찾을 수 있습니다 .
size_t
표현할 수 있는 정확한 범위의 값을 알고 있기를 바랍니다 . 그렇지 않은 경우 누가합니까?
Classic C (Brian Kernighan과 Dennis Ritchie가 The C Programming Language, Prentice-Hall, 1978 년에 기술 한 C의 초기 방언)는 제공하지 않았다 size_t
. size_t
이식성 문제를 해결하기 위해 C 표준위원회 소개
요컨대, size_t
부정적이지 않으며, 대상 플랫폼에서 가능한 가장 큰 객체의 크기를 나타내기에 충분히 크지 않지만 너무 크지 않은 부호없는 정수 유형으로 typedef이기 때문에 성능을 최대화합니다.
크기는 음수이면 안되며 실제로 size_t
부호없는 유형입니다. 또한 size_t
부호가 없으므로 부호없는 정수의 다른 모든 비트와 같이 부호 비트를 사용하여 크기를 나타낼 수 있기 때문에 해당 부호있는 유형보다 약 두 배 큰 숫자를 저장할 수 있습니다. 비트를 하나 더 얻으면, 표현할 수있는 숫자의 범위에 약 2 배를 곱합니다.
그래서 당신은 묻습니다. 왜 그냥 unsigned int
? 큰 숫자를 보유하지 못할 수 있습니다. unsigned int
32 비트 인 구현에서 나타낼 수있는 가장 큰 숫자는입니다 4294967295
. IP16L32와 같은 일부 프로세서는 4294967295
바이트 보다 큰 객체를 복사 할 수 있습니다 .
그래서, 당신은 묻지 unsigned long int
않습니까? 일부 플랫폼에서 성능이 저하됩니다. 표준 C는 long
32 비트 이상을 차지 해야합니다 . IP16L32 플랫폼은 각 32 비트 길이를 한 쌍의 16 비트 워드로 구현합니다. 이 플랫폼의 거의 모든 32 비트 연산자는 두 개의 16 비트 청크에서 32 비트와 함께 작동하기 때문에 두 개 이상의 명령이 필요합니다. 예를 들어, 32 비트 길이를 이동하려면 일반적으로 각 16 비트 청크를 이동하는 두 개의 기계 명령어가 필요합니다.
를 사용 size_t
하면이 성능이 저하됩니다. 이 환상적인 기사 에 따르면 , "유형 size_t
은 부호없는 정수 유형의 별칭 인 typedef입니다. 일반적으로 unsigned int
또는 unsigned long
가능할 수도 unsigned long long
있습니다. 각 표준 C 구현은 충분히 크지 만 필요한 것보다 크지 않은 부호없는 정수를 선택해야합니다. 대상 플랫폼에서 가능한 가장 큰 물체의 크기를 나타냅니다. "
unsigned int
시스템마다 다른 최대 값 . 할 필요가있어 적어도 65536
하지만 일반적입니다 4294967295
및 수 18446744073709551615
일부 시스템 (2 ** 64-1).
unsigned char
)에 대한 모든 절대 보장이 단순히 제거되었다는 인상을 받았습니다 . 표준은 문자열 '65535'또는 '65536'을 어디에도 포함하지 않는 것으로 보이며 '+32767'은 (1.9 : 9) 참고로 표현할 수있는 가장 큰 정수로 나타납니다 int
. INT_MAX
그것보다 작을 수 없다고 보장 할 수는 없습니다!
size_t 타입은 sizeof 연산자에 의해 반환되는 타입입니다. 호스트 시스템에서 지원되는 모든 메모리 범위의 크기를 바이트 단위로 표현할 수있는 부호없는 정수입니다. ptrdiff_t가 부호있는 정수 값이므로 sizeof (ptrdiff_t)와 sizeof (size_t)가 동일하다는 것은 (일반적으로) ptrdiff_t와 관련이 있습니다.
C 코드를 작성할 때는 메모리 범위를 다룰 때마다 항상 size_t 를 사용해야 합니다.
반면에 int 유형은 기본적으로 호스트 시스템이 정수 산술을 가장 효율적으로 수행하는 데 사용할 수있는 (부호있는) 정수 값의 크기로 정의됩니다. 예를 들어 많은 구형 PC 유형 컴퓨터에서 sizeof (size_t) 값은 4 (바이트)이지만 sizeof (int)는 2 (바이트)입니다. CPU는 최대 4GiB의 (논리적) 메모리 공간을 처리 할 수 있지만 16 비트 산술은 32 비트 산술보다 빠릅니다.
실제 정밀도는 컴파일러 옵션과 머신 아키텍처에 크게 좌우되므로 효율성에 관심이있는 경우에만 int 유형을 사용하십시오. 특히 C 표준은 다음과 같은 불변량을 지정합니다. sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) 각각에 대해 프로그래머가 사용할 수있는 정밀도의 실제 표현에는 다른 제한이 없습니다. 이러한 기본 유형.
참고 : 이것은 Java와 동일하지 않습니다 (실제로 'char', 'byte', 'short', 'int'및 'long'유형 각각의 비트 정밀도를 지정 함).
size_t
는 단일 객체의 크기 (예 : 숫자, 배열, 구조)를 나타낼 수 있습니다. 전체 메모리 범위는 다음을 초과 할 수 있습니다.size_t
size_t
함을 의미합니다. 대부분의 경우 주소 공간 + 이식성의 카디널리티가 중요한 배열은 다루지 않습니다. 이 경우에 당신은 걸릴 것 size_t
입니다. 다른 모든 경우에는 (부호있는) 정수에서 인덱스를 가져옵니다. 서명되지 않은 언더 플로 동작에서 발생하는 혼동 (경고없이 제공됨)이 다른 경우에 발생할 수있는 이식성 문제보다 더 일반적이고 더 나쁩니다.
size_t 유형은 가능한 객체의 크기를 저장하기에 충분히 커야합니다. 부호없는 int는 해당 조건을 만족시킬 필요가 없습니다.
예를 들어 64 비트 시스템에서 int 및 unsigned int는 32 비트 너비 일 수 있지만 size_t는 4G보다 큰 숫자를 저장하기에 충분히 커야합니다.
size_t
컴파일러가 sizeof (X)가 4G보다 큰 값을 생성하도록 X 유형을 허용 할 수 있다면 그 크기 만 커야 한다고 생각 합니다. 대부분의 컴파일러는 예를 들어 거부 할 것이라고 typedef unsigned char foo[1000000000000LL][1000000000000LL]
도하고, foo[65536][65536];
그것을 문서화 구현 정의 된 제한을 초과하는 경우 합법적으로 거부 할 수있다.
glibc 매뉴얼 0.02에서 발췌 한 내용은 다음 주제를 연구 할 때도 관련이있을 수 있습니다.
2.4 이전의 size_t 유형 및 GCC 버전에는 잠재적 인 문제가 있습니다. ANSI C에서는 size_t가 항상 부호없는 유형이어야합니다. 기존 시스템의 헤더 파일과의 호환성을 위해 GCC는 stddef.h' to be whatever type the system's
sys / types 에서 size_t를 정의합니다 .h '는이를 정의합니다. `sys / types.h '에서 size_t를 정의하는 대부분의 유닉스 시스템은이를 서명 된 유형으로 정의합니다. 라이브러리의 일부 코드는 size_t가 서명되지 않은 유형에 따라 다르며 서명 된 경우 올바르게 작동하지 않습니다.
size_t가 부호없는 것으로 예상되는 GNU C 라이브러리 코드가 정확합니다. 서명 된 유형으로 size_t의 정의가 올바르지 않습니다. 버전 2.4에서는 GCC가 size_t를 부호없는 유형으로 정의하고 fixincludes' script will massage the system's
sys / types.h '와 충돌하지 않도록 항상 계획합니다 .
그 동안 GNU C 라이브러리를 컴파일 할 때 GCC에 size_t에 부호없는 유형을 사용하도록 명시 적으로 지정하여이 문제를 해결합니다. `configure '는 필요한 경우 GCC가 size_t를 재정의하기 위해 사용하는 유형을 자동으로 감지합니다.
내 컴파일러가 32 비트로 설정된 size_t
경우에 대한 typedef 이외의 아무것도 아닙니다 unsigned int
. 내 컴파일러가 64 비트로 설정된 size_t
경우에 대한 typedef 이외의 아무것도 아닙니다 unsigned long long
.
unsigned long
일부 OS에서 두 경우 모두에 대해 정의 할 수 있습니다 .
size_t는 포인터의 크기입니다.
따라서 32 비트 또는 공통 ILP32 (정수, 긴 포인터) 모델 size_t에서 32 비트입니다. 64 비트 또는 공통 LP64 (long, pointer) 모델 size_t는 64 비트입니다 (정수는 여전히 32 비트 임).
다른 모델도 있지만 g ++에서 사용하는 모델입니다 (최소한 기본적으로)
size_t
일반적으로 포인터와 크기가 반드시 동일하지는 않습니다. 포인터는 메모리의 임의의 위치를 가리킬 수 있어야합니다. size_t
가장 큰 단일 객체의 크기를 나타낼만큼 충분히 커야합니다.