서명되지 않은 정수를 사용하여 코드와 의도를보다 명확하게 만듭니다. 부호있는 유형과 부호없는 유형으로 산술을 수행 할 때 예기치 않은 암시 적 변환을 방지하기 위해 서명하지 않은 변수에 부호없는 짧은 (일반적으로 2 바이트)을 사용하는 것입니다. 이것은 몇 가지 이유로 효과적입니다.
- 부호없는 짧은 변수 및 리터럴 (int 유형) 또는 int 유형의 변수로 산술을 수행하면 int는 항상 short보다 높은 순위를 가지므로 표현식을 평가하기 전에 부호없는 변수가 항상 int로 승격됩니다 . 이렇게하면 표현식의 결과가 물론 부호있는 정수에 적합하다고 가정 할 때 부호있는 유형과 부호없는 유형으로 산술을 수행하는 예기치 않은 동작이 발생하지 않습니다.
- 대부분의 경우 사용중인 부호없는 변수는 부호없는 2 바이트 short (65,535)의 최대 값을 초과하지 않습니다.
일반적으로 서명되지 않은 변수의 유형은 서명 된 유형으로 승격시키기 위해 서명 된 변수의 유형보다 순위가 낮아야합니다. 그러면 예기치 않은 오버플로 동작이 발생하지 않습니다. 분명히 이것을 항상 보장 할 수는 없지만 대부분 이것을 보장하는 것이 가능합니다.
예를 들어 최근에 다음과 같은 for 루프가 있습니다.
const unsigned short cuint = 5;
for(unsigned short i=0; i<10; ++i)
{
if((i-2)%cuint == 0)
{
//Do something
}
}
리터럴 '2'는 int 유형입니다. 내가 부호없는 short 대신 부호없는 int 인 경우 하위 표현식 (i-2)에서 2는 부호없는 int로 승격됩니다 (부호없는 int가 부호있는 int보다 우선 순위가 높기 때문에). i = 0이면 하위 표현식은 오버플로로 인해 (0u-2u) = 일부 대규모 값과 같습니다. i = 1과 동일한 아이디어입니다. 그러나 i는 부호가없는 short이므로 int로 서명 된 리터럴 '2'와 동일한 유형으로 승격되며 모든 것이 올바르게 작동합니다.
안전성 향상을 위해 : 드물게 구현하는 아키텍처가 int를 2 바이트로 만드는 경우 부호없는 짧은 변수가 맞지 않는 경우 산술 표현식의 두 피연산자가 모두 부호없는 int로 승격 될 수 있습니다. 부호가있는 2 바이트 int로 들어가고, 후자는 최대 값이 32,767 <65,535입니다. (참조 https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned을 자세한 내용). 이를 막기 위해 다음과 같이 프로그램에 static_assert를 추가하면됩니다.
static_assert(sizeof(int) == 4, "int must be 4 bytes");
int가 2 바이트 인 아키텍처에서는 컴파일되지 않습니다.
for(unsigned int n = 10; n >= 0; n --)
(무한 루프 반복)