부호 있는 정수 변수에는 C 언어에서 랩어라운드 동작이 없습니다.산술 계산 중 부호 있는 정수 오버플로로 인해 정의되지 않은 동작.당신이 언급한 GCC 컴파일러는 구현으로 알려져 있습니다. 엄격한 오버플로 의미 최적화에서는 정의되지 않은 동작 상황에서 제공되는 자유를 활용한다는 의미입니다.GCC 컴파일러는 부호 있는 정수 값이 절대 순환되지 않는다고 가정합니다.이는 GCC가 실제로 당신이 사용하는 컴파일러 중 하나라는 것을 의미합니다. 할 수 없다 부호 있는 정수 유형의 랩 어라운드 동작에 의존합니다.
예를 들어, GCC 컴파일러는 변수에 대해 다음과 같이 가정할 수 있습니다. int i
다음 조건
if (i > 0 && i + 1 > 0)
단순한 것과 동일하다
if (i > 0)
바로 이것이다 엄격한 오버플로 의미 수단.
부호 없는 정수 유형은 모듈로 산술을 구현합니다.모듈로는 동일합니다. 2^N
어디 N
유형의 값 표현에 있는 비트 수입니다.이러한 이유로 부호 없는 정수 유형은 실제로 오버플로 시 래핑되는 것처럼 보입니다.
그러나 C 언어는 C 언어보다 작은 영역에서 산술 계산을 수행하지 않습니다. int
/unsigned int
.유형 unsigned short int
귀하의 질문에서 언급한 내용은 일반적으로 다음 유형으로 승격됩니다. int
계산이 시작되기 전 표현식에서(범위가 다음과 같다고 가정) unsigned short
의 범위에 들어맞는다 int
).이는 1) 다음과 같은 계산을 의미합니다. unsigned short int
의 영역에서 수행될 예정이다. int
, 다음과 같은 경우 오버플로가 발생합니다. int
2) 이러한 계산 중 오버플로는 랩 어라운드 동작이 아닌 정의되지 않은 동작으로 이어집니다.
예를 들어, 이 코드는 랩 어라운드를 생성합니다.
unsigned i = USHRT_MAX;
i *= INT_MAX; /* <- unsigned arithmetic, overflows, wraps around */
이 코드는 동안
unsigned short i = USHRT_MAX;
i *= INT_MAX; /* <- signed arithmetic, overflows, produces undefined behavior */
정의되지 않은 동작으로 이어집니다.
그렇지 않은 경우 int
오버플로가 발생하고 결과는 다시 unsigned short int
유형, 다시 모듈로로 감소됩니다. 2^N
, 이는 값이 래핑된 것처럼 나타납니다.