고정폭 정수형(예: uint8_t)을 사용하지 않는 이유가 있습니까?
C99(또는 stdint.h)를 지원하는 컴파일러를 사용한다고 가정할 때 uint8_t와 같은 고정폭 정수형을 사용하지 않을 이유가 있습니까?
제가 알고 있는 한 가지 이유는 이 제품을 사용하는 것이 훨씬 더 합리적이기 때문입니다.char
를 사용하는 대신 문자를 다룰 때(u)int8_t
s, 이 질문에서 설명한 바와 같이.
하지만 숫자를 저장할 계획이라면 크기가 얼마나 큰지 모르는 유형을 언제 사용하고 싶습니까?즉, 어떤 상황에서 번호를 저장하시겠습니까?unsigned short
8비트, 16비트, 32비트 중 어느 쪽을 사용하는지 모르는 상태에서uint16t
?
이어서, 고정 폭의 정수를 사용하는 것이 더 나은 관행으로 간주됩니까, 아니면 일반적인 정수 유형을 사용하고 아무것도 가정하지 않고 사용하는 것이 더 나은 관행으로 간주됩니까?sizeof
사용 빈도가 얼마나 되는지 알 수 있습니까?
실제로 정확한 글자 크기를 알 필요 없이 숫자를 저장하는 것은 매우 일반적입니다.내 프로그램에는 20억을 넘지 않을 것이라고 합리적으로 가정하거나 그렇지 않다고 강제할 수 있는 수량이 많이 있습니다.그러나 정확한 32비트 타입이 필요한 것은 아닙니다.최소 20억까지 셀 수 있는 타입이라면 저는 상관없습니다.
휴대용 코드를 작성하려는 경우 고정 너비 유형은 모두 옵션이라는 점에 유의해야 합니다.
C99의 실장에서는,CHAR_BIT
보다 크다8
거기에는 없다int8_t
표준에서는 패딩 비트가 필요하기 때문에 존재하지 않습니다.intN_t
타입은 패딩 비트(7.18.1.1/1)를 가지지 않도록 정의되어 있습니다. uint8_t
따라서 (고맙게도) 구현은 정의될 수 없기 때문에uint8_t
없이.int8_t
.
따라서 매우 휴대용 코드에서는 최대 127개의 값을 저장할 수 있는 서명된 유형이 필요한 경우 다음 중 하나를 사용해야 합니다.signed char
,int
,int_least8_t
또는int_fast8_t
컴파일러에 의뢰할 것인지 여부에 따라 다음 절차를 수행합니다.
- C89에서 작업(
signed char
또는int
) - 산술식에서의 놀라운 정수 승진을 피한다(
int
) - 작다(
int_least8_t
또는signed char
) - 고속 (
int_fast8_t
또는int
)
최대 255의 부호 없는 타입에 대해서도 마찬가지입니다.unsigned char
,unsigned int
,uint_least8_t
그리고.uint_fast8_t
.
modulo-256 의 연산이 매우 포터블한 코드로 필요한 경우는, 직접 modulus 를 취득하거나, 비트를 마스크 하거나, 비트필드를 사용한 게임을 하거나 할 수 있습니다.
실제로 대부분의 사람들은 그렇게 휴대할 수 있는 코드를 쓸 필요가 없다.그 순간.CHAR_BIT > 8
전용 하드웨어에서만 사용할 수 있고 범용 코드는 사용되지 않습니다.물론 미래에 바뀔 수도 있지만, 만약 그렇다면 Posix나 Windows에 대해 추측하는 코드가 너무 많을 것으로 생각됩니다(둘 다 보증합니다).CHAR_BIT == 8
코드 이식 불가에 대처하는 것은 새로운 플랫폼에 코드를 이식하는 큰 작업의 일부입니다.그러한 실장에서는, 코드를 어떻게 기동해 실행할지에 대해 고민하기 전에, 인터넷(옥텟 대응)에의 접속 방법에 대해 고민할 필요가 있습니다.
만약 당신이 그렇게 가정한다면CHAR_BIT == 8
어쨌든, 저는 특별히 피할 이유가 없다고 생각합니다.(u)int8_t
단, C89에서 코드가 동작하는 경우는 제외합니다.C89에서도 버전을 찾거나 쓰는 것은 그리 어렵지 않습니다.stdint.h
특정 구현에 사용됩니다.하지만 타입이 유지할 수 있는 것만을 요구하는 코드를 쉽게 작성할 수 있습니다.255
버틸 수 없는 것이 아니라256
그럼, 에 대한 의존을 피하는 것이 좋습니다.CHAR_BIT == 8
.
아직 언급되지 않은 한 가지 문제는 고정 크기의 정수형을 사용하는 것은 컴파일러가 다른 크기를 사용하는 경우 변수 크기가 변경되지 않는다는 것입니다.int
,long
크기가 정의되어 있는 경우에도 다양한 정수 크기를 가진 머신에서 코드가 동일하게 동작하는 것은 보증되지 않습니다.
예를 들어, 지정된 선언은uint32_t i;
, 표현의 동작(i-1) > 5
언제i
이 0은, 의 유무에 따라 다릅니다.uint32_t
보다 작다int
. 예를 들어 다음과 같은 시스템입니다. int
64비트(및uint32_t
뭐랄까long short
변수)i
로 승진할 것이다int
; 감산 및 비교는 부호(-1은 5보다 작음)로 수행됩니다.다음과 같은 시스템의int
32비트, 감산 및 비교는 다음과 같이 수행됩니다.unsigned int
(감산하면 5보다 큰 큰 숫자가 나옵니다).
부호 없는 타입을 포함한 식의 중간 결과는 타입캐스트가 없는 경우에도 랩해야 한다는 사실에 얼마나 의존하는지 모른다(IMHO, 랩 동작을 원했다면 프로그래머는 타입캐스트를 포함했어야 한다).(uint32_t)(i-1) > 5
그러나 현재 표준에서는 여유를 허용하지 않습니다.나는 컴파일러가 적어도 형식 캐스트나 형식 강제가 없을 때 피연산자를 더 긴 정수형으로 승격시키는 것을 허용한 규칙이 주어진다면 어떤 문제가 발생할지 궁금하다.uint32_t i,j
, 과 같은 과제j = (i+=1) >> 1;
넘쳐나는 것을 잘라내야 할 것이다.j = (uint32_t)(i+1) >> 1;
,그렇지만j = (i+1)>>1
안 될까요?또는 컴파일러 제조업체가 중간 결과가 가장 큰 서명된 유형에 모두 적합하고 일정하지 않은 양에 의한 올바른 이동이 수반되지 않는 적분형 식을 보증하는 것이 얼마나 어려울까요?제가 보기엔 좀 이상하게 느껴지는데요.int
32비트:
uint64_t a, b, c;...a &= ~0x40000000;b & = ~0x80000000;c & = ~0x180000;
1비트씩 클리어하다a
그리고.c
단, 상위 33비트는 클리어합니다.b
; 대부분의 컴파일러는 두 번째 식에 대해 아무것도 '다른' 것이 없음을 암시하지 않습니다.
를 사용하고 싶은 이유는 여러 가지가 있습니다.이것들을 의미형이라고 부릅니다.int
또는char
와 같은 고정폭 타입에 걸쳐서uint8_t
:
기존 API 일치
Standard Clib는char*
온통.왜 API와 대화할 때 다른 유형을 사용하여 사용자를 혼란스럽게 합니까? (또한 버그도 발생할 수 있습니다.)
유사하게,printf()
형식 문자열은 이러한 의미 유형의 관점에서 정의됩니다.고정 사이즈 타입을 인쇄하려면 , 다음과 같은 매크로가 필요합니다.PRIu64
등입니다.stdint.h
이전 글꼴을 사용하여 고정 크기 활자를 인쇄하기 위한 올바른 형식 문자열을 얻을 수 있습니다.printf
형식을 지정합니다.
스피드
의미 유형은 일반적으로 현재 CPU의 성능 특성에 가장 잘 작동하도록 선택됩니다.CPU의 레지스터 크기이기 때문에 불필요한 변환 등을 절약할 수 있기 때문에 선택한 크기보다 약간 더 큰 사이즈가 될 수 있습니다.
요즘 이것은 약간 논쟁의 여지가 있는 대답입니다... 원래 의도였던 것 때문에stdint
초기 C/C++에서는 사용할 수 없습니다.많은 플랫폼(32비트 Windows 또는 MacOS X 등)에서는int
그리고.long
64비트를 이동하는 동안 일부 사이즈는 그대로 유지되었습니다(그 결과 다음과 같은 새로운 타입이 등장했습니다).long long
(다른 것 같습니다.그래서 우리가 이 모든 걸었던 거야least
그리고.fast
종류들.
코드 휴대성
64비트 플랫폼에서는 32비트 플랫폼보다 시멘틱타입이 클 수 있습니다(예를 들어 어레이인덱스가 모든 메모리를 채울 수 있도록 합니다).따라서 다른 플랫폼에서 실행 중인 경우 시멘틱 유형을 사용합니다(제 정의에 따르면 다음과 같습니다).size_t
고정 하드웨어가 아닌 임의의 제한을 추가하지 않고 더 나은 하드웨어를 활용한다는 것을 의미합니다.
물론, 이것은 알고리즘만 휴대 가능하게 합니다.데이터를 바이트로 시리얼화하여 다른 플랫폼 간에 교환해야 하는 경우, 이로 인해 코드가 이식 가능해질 수 있지만 네트워크 패킷이나 출력 파일은 사용할 수 없습니다.따라서 이 경우 특정 플랫폼에서 코드가 너무 느리게 실행되거나 컴파일되지 않는 대신 데이터가 이동 가능한 상태로 유지되도록 고정 유형을 사용해야 합니다.
코멘트:포맷 스트링을 도입하지 않은 이유는 묻지 마십시오.int64_t
,int32_t
편지가 다 떨어졌을까?너무 많은 코드베이스가 자체 형식 문자열을 정의하여 고장났을 수도 있습니다.
코드는 캐주얼한 독자(및 프로그래머 자신)에게 무엇이 중요한지 밝혀야 합니다.그냥 정수인가, 부호 없는 정수인가, 부호 있는 정수인가?사이즈도 마찬가지입니다.일부 변수가 기본 16비트인 것이 알고리즘에 정말 중요합니까?아니면 단지 불필요한 세밀한 관리와 최적화에 실패한 시도일까요?
이것이 프로그래밍을 예술로 만드는 것입니다. 무엇이 중요한지를 보여주기 위해서입니다.
표준 정수 유형의 폭은 플랫폼 간에 변경될 수 있지만 최소 폭은 변경할 수 없습니다.
예를 들어, C 표준은 다음과 같이 규정하고 있습니다.int
적어도16-bit
및 along
적어도32-bit
넓은.
개체를 저장할 때 크기 제한이 없는 경우 이를 구현에 적용할 수 있습니다.예를 들어, 서명된 최대값이 에 적합한 경우16-bit
그냥 사용하시면 됩니다.int
그 후, 실장에 대해서, 무엇이 자연스러운지에 대한 최종적인 설명을 실시합니다.int
구현 대상이 되는 아키텍처의 폭.
너비를 가정할 때는 고정 너비 유형만 사용해야 합니다.
uint8_t
그리고.unsigned char
대부분의 플랫폼에서 동일하지만 모든 플랫폼에서는 동일하지 않습니다.사용.uint8_t
8비트의 아키텍처가 있다고 가정하고 있다는 사실을 강조합니다.char
컴파일을 하지 않기 때문에, 이것이 특징입니다.
그렇지 않으면 '의미적'을 사용해서typedef
예를 들어size_t
,uintptr_t
,ptrdiff_t
데이터에 대해 생각하고 있는 것을 훨씬 더 잘 반영하고 있기 때문입니다.베이스 타입은 거의 직접 사용하지 않습니다.int
에러 반환을 위해서만, 지금까지 사용한 적이 없습니다.short
.
편집: C11을 주의 깊게 읽은 후 다음과 같이 결론짓습니다.uint8_t
존재하는 경우는, 다음과 같이 할 필요가 있습니다.unsigned char
그럴 순 없어char
해당 유형이 서명되지 않은 경우에도 마찬가지입니다.이것은 7.20.1 p1의 요건에서 비롯됩니다.intN_t
그리고.uintN_t
대응하는 부호 있는 유형과 부호 없는 유형이어야 합니다.문자 타입의 유일한 쌍은 다음과 같습니다.signed char
그리고.unsigned char
.
언급URL : https://stackoverflow.com/questions/13413521/is-there-any-reason-not-to-use-fixed-width-integer-types-e-g-uint8-t
'programing' 카테고리의 다른 글
php에서 실행 시간 초과를 늘리는 방법 (0) | 2022.10.12 |
---|---|
JavaScript에서 랜덤 문자열/문자 생성 (0) | 2022.10.12 |
Python에서 날짜를 datetime으로 변환 (0) | 2022.10.12 |
아나콘다 대 미니콘다 (0) | 2022.10.12 |
배열에서 가장 높은 키/인덱스 검색 (0) | 2022.10.12 |