문제
작은 샘플 기능이 있습니다.
#define VALUE 0
int test(unsigned char x) {
if (x>=VALUE)
return 0;
else
return 1;
}
내 컴파일러는 모든 경우에 비교 (x> = value)가 사실이라고 경고합니다. x는 서명되지 않은 문자이고 값은 값 0으로 정의되므로 코드를 다음과 같이 변경했습니다.
if ( ((signed int) x ) >= ((signed int) VALUE ))
그러나 경고는 다시 온다. 3 개의 GCC 버전으로 테스트했습니다 (모든 버전> 4.0, 때로는 -wextra를 활성화해야합니다).
변경된 경우, 나는이 명시 적 캐스트가 있으며 서명 된 INT 비교 여야합니다. 왜 비교가 항상 사실이라고 주장 하는가?
해결책
캐스트에도 불구하고 정의 된 행동의 모든 경우에서 비교는 여전히 사실입니다. 컴파일러는 여전히이를 결정합니다 (signed int)0
값 0이 있고 여전히 결정합니다 (signed int)x)
프로그램이 동작을 정의한 경우 음이 무분별하지 않습니다 (서명되지 않은 것에서 서명으로 캐스팅하는 것은 값이 서명 된 유형의 범위를 벗어난 경우 정의되지 않음).
따라서 컴파일러는 다른 케이스를 완전히 제거하기 때문에 계속 경고합니다.
편집하다: 경고를 침묵 시키려면 코드를 작성하십시오.
#define VALUE 0
int test(unsigned char x) {
#if VALUE==0
return 1;
#else
return x>=VALUE;
#endif
}
다른 팁
x
이다 unsigned char
, 그것은 0에서 256 사이입니다. int
a보다 큽니다 char
, 캐스팅 unsigned char
에게 signed int
여전히 보유합니다 char
원래 가치. 이 값은 항상> = 0이므로 if
항상 사실입니다.
An의 모든 값 unsigned char
당신에게 완벽하게 불을 붙일 수 있습니다 int
, 캐스트에도 불구하고 당신은 결코 부정적인 가치를 얻지 못할 것입니다. 당신이 필요한 캐스트는 signed char
- 그러나이 경우 선언해야합니다 x
~처럼 signed
함수 서명에서. 고객에게 서명되지 않은 값이 필요하다는 점은 없지만 실제로 서명 된 값이 필요하다는 점은 없습니다.
그만큼 #define
의 VALUE
에게 0
기능이 이것으로 줄어드는 것을 의미합니다.
int test(unsigned char x) {
if (x>=0)
return 0;
else
return 1;
}
부터 x
항상 안으로 들어갑니다 unsigned char
, 그러면 항상 사이에 값이 있습니다 0
그리고 255
캐스트 여부에 관계없이 포괄적입니다 x
또는 0
a signed int
에서 if
성명. 따라서 컴파일러는 당신에게 경고합니다 x
항상 이상 또는 동일합니다 0
, 그리고 그게 else
조항에 도달 할 수 없습니다.