2011-12-19 2 views
5

경고 수준/W4를 사용하는 Visual Studio 2010 C++ 컴파일러 (X86)를 사용하여 다음 C++ 프로그램을 컴파일하려고하면 다음과 같이 서명 된/서명되지 않은 불일치 경고가 발생합니다. 표시된 선.C++ : 부호없는 형식 만 사용하는 경우 부호있는/부호없는 불일치

#include <cstdio> 
#include <cstdint> 
#include <cstddef> 

int main(int argc, char **argv) 
{ 
    size_t idx = 42; 
    uint8_t bytesCount = 20; 

    // warning C4389: '==' : signed/unsigned mismatch 
    if (bytesCount + 1 == idx) 
    { 
     printf("Hello World\n"); 
    } 

    // no warning 
    if (bytesCount == idx) 
    { 
     printf("Hello World\n"); 
    } 
} 

저는 부호없는 유형만을 사용하기 때문에 혼란 스럽습니다.

bytesCount == idx 

은 그러한 경고가 발생하지 않습니다 비교 때문에, 아마 여기 일이 이상한 암시 적 대화를 함께 할 수있다.

따라서이 경고를받는 이유는 무엇이며 어떤 규칙에 따라이 대화가 발생합니까 (이것이 이유 일 경우)?

답변

5

1int입니다. 정수 연산 식의 유형은 관련된 유형에 따라 다릅니다. 이 경우 unsigned 유형과 unsigned 유형이 signed 유형보다 작은 signed 유형이 있습니다. 이 표현에서 C++ 표준에 해당 (섹션 5.10 [EXPR]) :

그렇지 않으면 부호있는 정수 타입 피연산자의 유형은 서명되지 않은 와 피연산자의 타입의 모든 값을 나타낼 수있는 경우 정수형의 경우 부호없는 정수형의 피연산자는 부호 첨부 정수형의 피연산자 형식으로 환산 이됩니다. 즉

, 표현 bytesCount + 1의 유형은 기본적으로 서명 int입니다.

9

1은 서명 된 리터럴입니다. bytesCount + 1U를 시도하십시오. 1 형 intbytesCount + 1int 인 표현이기 때문에

컴파일러 아마도 서명 및 서명 값 (bytesCount + 1)

3

의 첨가에 의한 부호 입력의 임시 값을 생성한다 (부호).

int보다 작은 유형은 int을 촉진 수학 식에 사용 너무도 + bytesCountbytesCount + bytesCountuint8_tint을 고려하지되는 사실 (bytesCount + 1U가 인 이후 unsigned int 동안 int보다크다) .

following programtrue을 세 번 출력합니다.

#include <iostream> 

int main() 
{ 
    unsigned short s = 1; 
    std::cout << (&typeid(s + 1U) == &typeid(1U)) << std::endl; 
    std::cout << (&typeid(+ s) == &typeid(1)) << std::endl; 
    std::cout << (&typeid(s + s) == &typeid(1)) << std::endl; 
} 
1

다른 답변은 이미 bytesCount + 1signed int으로 해석되었음을 알려줍니다. 그러나 bytesCount == idx, bytesCount이고signed int으로 해석됩니다. 개념적으로, 그것은 처음에 signed int으로 변환되며, 그 후에는 unsigned int으로 변환됩니다. 컴파일러는 실제로 문제가 없다는 것을 알기에 충분한 정보가 있기 때문에 이에 대해 경고하지 않습니다. signed int으로 변환하면 bytesCount 음수가 될 수 없습니다.bytesCount + 1을 비교하는 것은 똑같이 유효하며 똑같이 안전하지만 컴파일러가 더 이상 안전하지 못하도록하기 위해 약간 더 복잡합니다.

+0

컴파일러에게 이러한 문제에 대해 경고하지 않는 방법, 프로그램 코드에서 비교가 안전하다는 것이 확실하다면 전체 파일에 대한 경고를 해제하고 싶지는 않지만 코드를 추하게 만들고 싶지는 않습니다. 그것을 피하십시오. 이를 달성 할 수있는 방법이 있습니까? – Arkady

+0

@Arkady 컴파일러가 코드에 대해 경고하도록 구성되어 있으면 코드가 변경되기를 원치 않으므로 (컴파일러의 구성을 변경하지 않으려 고합니다. 경고도), 당신은 많은 옵션을 열어두고 있지 않습니다. 내가 생각할 수있는 유일한 옵션은 분석을 개선하기 위해 컴파일러를 해킹하는 것입니다. – hvd