2010-02-14 3 views
5

부호가 있거나 부호가없는 불일치가 반드시 불량입니까?C89 : 부호있는/부호없는 불일치

서명
int main(int argc, char *argv[]) { 
    unsigned int i; 

    for (i = 1; i < argc; i++) { // signed/unsigned mismatch here 

    } 
} 

argc, i가 없습니다 :

여기 내 프로그램입니다. 이게 문제 야?

+0

잘 속는 사람은 아니지만 어쨌든 읽을만한 가치가 있습니다. http://stackoverflow.com/questions/859943/c-how-can-i-fix-warnings-like-comparison-between-signed-and-unsigned – finnw

답변

9

"signed/unsigned mismatches"가 좋지 않을 수 있습니다. 귀하의 질문에, 당신은 비교를 요구하고 있습니다. 동일한 기본 유형의 두 값 (부호가 하나이고 부호가없는 두 값)을 비교할 때 부호있는 값은 부호가없는 값으로 변환됩니다. i < j에, iunsigned int로 변환되기 때문에 그래서,

int i = -1; 
unsigned int j = 10; 

if (i < j) 
    printf("1\n"); 
else 
    printf("2\n"); 

인쇄이 아니라 1입니다. (unsigned int)-1은 매우 큰 숫자 인 UINT_MAX과 같습니다. 따라서 조건은 거짓으로 평가되고 else 절로 이동합니다.

특정 예로, argc은 음수가 아니므로 "불일치"에 대해 걱정할 필요가 없습니다.

+0

왜 부호가없는 부호로 변환 된 부호 (왜 그 반대입니까?) 이 행동은 표준화 되었습니까? – triclosan

+0

@triclosan, 예. 규칙은 약간 복잡하지만 'int'와 'unsigned int'의 경우 동일한 순위이므로 부호있는 유형은 부호없는 유형으로 변환됩니다. 6 절 참조.자세한 내용은 N1256의 3.1.8을 참조하십시오. –

1

실제 문제는 아니지만 컴파일러는 argc가 항상 문제를 일으키지 않는 값을 가질 수 있는지 알 수 없습니다.

+0

'argc'가 너무 커서'int'에 맞지 않으면 심각한 문제가 발생합니다 :-) – finnw

+0

꼭 그런 것은 아닙니다. 'INT_MAX '는 32767로 낮을 수 있으며 수백 킬로바이트를 초과하는 커맨드 라인을 보았습니다. xargs (1) 유틸리티는 그 한계에 쉽게 도달하는 것으로 알려져 있습니다. – Jens

1

간접적으로 문제가됩니다. 당신은 &, |, <<>> 같은 비트 연산에 대한 부호있는 정수를 사용하는 경우

나쁜 일이 발생할 수 있습니다. 당신이 혼합 할 때 산술 부호없는 정수를 사용하는 경우 (언더 플로우, 무한 루프 테스트 할 때 숫자가 >= 0 등의 경우)이 때문에


완전히 다른 나쁜 일이 일어날 수 있고, 어떤 컴파일러 및 정적 검사 도구는 경고를 발행합니다 어느 연산 유형 (산술 연산 또는 비트 조작)에서 부호가 있거나 부호없는 정수가 될 수 있습니다.

예와 같이 간단한 경우에는 혼합 할 수 있지만 그렇게하면 정적 검사 도구를 사용할 수 없음을 의미합니다 (또는 이러한 경고를 비활성화해야 함). 다른 버그가 발견되지 않을 수도 있습니다.

경우에 따라 선택의 여지가 없습니다. 메모리 관리 코드에서 size_t 유형의 값에 대한 산술을 수행 할 때.

당신의 예에서 나는 적은 유형을 가지고 간단해서, int에 충실 것, 그것이 main()에 첫 번째 인수의 형태가 그대로 int 어쨌든 거기가 될 것입니다.

1

나쁘지 않습니다. 기호/불일치 불일치에 관한 컴파일러 경고를 수정합니다. 왜냐하면 나쁜 일은있을 법하지 않거나 불가능할 수도 있기 때문입니다. 서명 된/서명되지 않은 불일치 때문에 버그를 수정해야 할 때 컴파일러는 기본적으로 "내가 그렇게 말했어"라고 말합니다. 그 이유에 대한 경고를 무시하지 마십시오.