2013-04-24 2 views
4

gcc 4.4.5-Wtype-limits 옵션을 사용하여 작은 코드 스 니펫을 테스트하고 있습니다.gcc는 -Wtype-limits를 어떻게 처리합니까?

main.c:7: warning: comparison is always false due to limited range of data type

그러나, 지금까지의 내가 아는 한, INT_MAXC11에서 (+32767 동일 할 수있다 (n1570), 5.2 § :

#include <assert.h> 
#include <limits.h> 
#include <stdint.h> 

int main(void) 
{ 
    /* With other values of v, the behavior of the compiler is the same. */ 
    uint16_t v = 0; 
    assert((unsigned int)INT_MAX < (unsigned int)v); /* l. 7 */ 
    return 0; 
} 

그런 다음, 컴파일러는 나에게 다음과 같은 경고가 발생합니다 .4.2.1 정수 유형의 크기 <limits.h>). 이 경우 변수 vINT_MAX+1 값을 보유 할 수 있으며 assert의 표현식은 1으로 평가됩니다.

따라서, 나는이 문제를 볼 수 있습니다 : 사실, INT_MAX+32767 동일하지 않습니다, 때문에

  • GCC는 계정 내 아키텍처를합니다. 이 경우 -Wtype-limits의 혜택이 줄어 듭니다.
  • 이것은 버그입니다.

제 생각에는 두 번째 옵션은 다음 옵션과 동일한 옵션으로 경고를 생성하지 않는 코드입니다.

#include <assert.h> 
#include <limits.h> 
#include <stdint.h> 

int main(void) 
{ 
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX); 
    return 0; 
} 

그래서 정답은 무엇인가?

PS : 그런데, 나는 때문에 GCC 내 이전 버전의 사과해야합니다. 다음 릴리스의 동작이 다를 수 있습니다.

+0

gcc가 'INT_MAX'의 가능한 값을 경고하도록 하시겠습니까? 또한 나는이 모든 것이 사전 처리 후에 완료 될 것이라고 기대할 것이다. 그래서이 경고를 확인할 때까지는 변수와 정수 상수를 비교하는 것이 전부다. –

답변

4

GCC는 실제 알려진 유형 제한을 고려합니다. 그것은 당신의 경우에 int이 16 비트 너비보다 넓다는 것을 알고 있으므로 경고합니다. 표준은 말한다 때문에

당신은

#include <assert.h> 
#include <limits.h> 
#include <stdint.h> 

int main(void) 
{ 
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX); 
    return 0; 
} 

에 대한 경고를 얻을 7.19.2 (2) :

정의 된 매크로의 각 인스턴스가 사용하기에 적합한 상수 표현으로 교체해야 사전 처리 지시문이 이고이 표현식은 정수 승격에 따라 변환 된 해당 유형의 객체 인 표현식과 동일한 유형이어야합니다.

때문에 32 비트 폭 int들과 매크로 UINT16_MAX은 따라서 참여 유형의 한계는 비교가 거짓 (또는 true)를 항상 보장하지 않는, int입니다.

+0

매우 명확한 대답입니다. 감사. – md5

관련 문제