development

부호없는 int와 size_t

big-blog 2020. 2. 14. 23:44
반응형

부호없는 int와 size_t


나는 현대 C 통지 및 C ++ 코드를 사용하는 것 size_t대신에 int/ unsigned int거의 모든 곳에서 - STL과에 C 문자열 함수에 대한 매개 변수에서. 나는 이것의 이유와 그것이 가져다주는 이점에 대해 궁금합니다.


size_t유형의 결과 인 부호없는 정수 타입 sizeof연산자 (그리고 offsetof이 시스템이 처리 할 수있는 가장 큰 객체 (예를 들면, 8GB의의 정적 배열)의 크기를 포함하도록 충분히 큰 보장되도록, 연산자).

size_t유형은보다보다 큰 같거나 작을 수있다 unsigned int, 당신의 컴파일러 최적화를 위해 그것에 대해 인식 할 수 있습니다.

인터넷에서 pdf 형식으로 제공되는 C99 표준 섹션 7.17, pdf 초안으로 제공되는 C11 표준 섹션 7.19 에서보다 정확한 정보를 찾을 수 있습니다 .


Classic C (Brent Kernighan과 Dennis Ritchie가 C 프로그래밍 언어, 1978 년 Prentice-Hall, 1978 년에 기술 한 C의 초기 방언)는 제공하지 않았다 size_t. size_t이식성 문제를 제거하기 위해 C 표준위원회 소개

embedded.com에 자세히 설명되어 있습니다 (아주 좋은 예)


요컨대, size_t부정적이지 않으며 대상 플랫폼에서 가능한 가장 큰 객체의 크기를 나타내기에 충분히 크지 않지만 너무 크지 않은 부호없는 정수 유형으로 typedef이기 때문에 성능을 최대화합니다.

크기는 음수이면 안되며 실제로 size_t부호없는 유형입니다. 또한 size_t부호가 없으므로 부호없는 정수의 다른 모든 비트와 같이 부호 비트를 사용하여 크기를 나타낼 수 있기 때문에 해당 부호있는 유형보다 약 두 배 큰 숫자를 저장할 수 있습니다. 하나 더 많은 비트를 얻었을 때 표현할 수있는 숫자의 범위에 약 2 배를 곱합니다.

그래서 당신은 묻습니다. 왜 그냥 unsigned int? 큰 숫자를 보유하지 못할 수 있습니다. unsigned int32 비트 인 구현에서 나타낼 수있는 가장 큰 숫자는입니다 4294967295. IP16L32와 같은 일부 프로세서는 4294967295바이트 보다 큰 객체를 복사 할 수 있습니다 .

그래서, 당신은 묻지 unsigned long int않습니까? 일부 플랫폼에서 성능이 저하됩니다. 표준 C는 long32 비트 이상을 차지 해야합니다 . IP16L32 플랫폼은 각 32 비트 길이를 한 쌍의 16 비트 워드로 구현합니다. 이 플랫폼의 거의 모든 32 비트 연산자는 두 개의 16 비트 청크에서 32 비트와 함께 작동하기 때문에 두 개 이상의 명령어가 필요합니다. 예를 들어, 32 비트 길이를 이동하려면 일반적으로 각각의 16 비트 청크를 이동하는 두 개의 기계 명령어가 필요합니다.

를 사용 size_t하면 이러한 성능 저하 피할 수 있습니다. 이 환상적인 기사 에 따르면 , "유형 size_t은 부호없는 정수 유형의 별칭 인 typedef입니다. 일반적으로 unsigned int또는 unsigned long가능할 수도 unsigned long long있습니다. 각 표준 C 구현은 충분히 크지 만 필요한 것보다 크지 않은 부호없는 정수를 선택해야합니다. 대상 플랫폼에서 가능한 가장 큰 물체의 크기를 나타냅니다. "


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 유형은 가능한 객체의 크기를 저장하기에 충분히 커야합니다. 부호없는 int는 해당 조건을 충족시킬 필요가 없습니다.

예를 들어 64 비트 시스템에서 int 및 unsigned int는 32 비트 너비 일 수 있지만 size_t는 4G보다 큰 숫자를 저장하기에 충분히 커야합니다.


glibc 매뉴얼 0.02에서 발췌 한 내용은 다음 주제를 연구 할 때도 관련이있을 수 있습니다.

2.4 이전의 size_t 유형 및 GCC 버전에는 잠재적 인 문제가 있습니다. ANSI C에서는 size_t가 항상 부호없는 유형이어야합니다. 기존 시스템의 헤더 파일과의 호환성을 위해 GCC는 stddef.h' to be whatever type the system'ssys / 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'ssys / types.h '와 충돌하지 않도록 항상 계획합니다 .

그 동안 GNU C 라이브러리를 컴파일 할 때 size_t에 부호없는 유형을 사용하도록 GCC에 명시 적으로 지정하여이 문제를 해결합니다. `configure '는 필요한 경우 GCC가 size_t 배열을 재정의하기 위해 사용하는 유형을 자동으로 감지합니다.


내 컴파일러가 32 비트로 설정된 size_t경우에 대한 typedef 이외의 아무것도 아닙니다 unsigned int. 내 컴파일러가 64 비트로 설정된 size_t경우에 대한 typedef 이외의 아무것도 아닙니다 unsigned long long.


size_t는 포인터의 크기입니다.

따라서 32 비트 또는 공통 ILP32 (정수, 긴 포인터) 모델 size_t에서 32 비트입니다. 64 비트 또는 공통 LP64 (long, pointer) 모델 size_t는 64 비트입니다 (정수는 여전히 32 비트 임).

다른 모델도 있지만 g ++에서 사용하는 모델입니다 (최소한 기본적으로)

참고 URL : https://stackoverflow.com/questions/131803/unsigned-int-vs-size-t



반응형