부호가 있거나 부호가없는 불일치가 반드시 불량입니까?C89 : 부호있는/부호없는 불일치
서명int main(int argc, char *argv[]) {
unsigned int i;
for (i = 1; i < argc; i++) { // signed/unsigned mismatch here
}
}
argc
, i
가 없습니다 :
여기 내 프로그램입니다. 이게 문제 야?
부호가 있거나 부호가없는 불일치가 반드시 불량입니까?C89 : 부호있는/부호없는 불일치
서명int main(int argc, char *argv[]) {
unsigned int i;
for (i = 1; i < argc; i++) { // signed/unsigned mismatch here
}
}
argc
, i
가 없습니다 :
여기 내 프로그램입니다. 이게 문제 야?
"signed/unsigned mismatches"가 좋지 않을 수 있습니다. 귀하의 질문에, 당신은 비교를 요구하고 있습니다. 동일한 기본 유형의 두 값 (부호가 하나이고 부호가없는 두 값)을 비교할 때 부호있는 값은 부호가없는 값으로 변환됩니다. i < j
에, i
가 unsigned 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
은 음수가 아니므로 "불일치"에 대해 걱정할 필요가 없습니다.
왜 부호가없는 부호로 변환 된 부호 (왜 그 반대입니까?) 이 행동은 표준화 되었습니까? – triclosan
@triclosan, 예. 규칙은 약간 복잡하지만 'int'와 'unsigned int'의 경우 동일한 순위이므로 부호있는 유형은 부호없는 유형으로 변환됩니다. 6 절 참조.자세한 내용은 N1256의 3.1.8을 참조하십시오. –
간접적으로 문제가됩니다. 당신은 &
, |
, <<
및 >>
같은 비트 연산에 대한 부호있는 정수를 사용하는 경우
나쁜 일이 발생할 수 있습니다. 당신이 혼합 할 때 산술 부호없는 정수를 사용하는 경우 (언더 플로우, 무한 루프 테스트 할 때 숫자가 >= 0
등의 경우)이 때문에
완전히 다른 나쁜 일이 일어날 수 있고, 어떤 컴파일러 및 정적 검사 도구는 경고를 발행합니다 어느 연산 유형 (산술 연산 또는 비트 조작)에서 부호가 있거나 부호없는 정수가 될 수 있습니다.
예와 같이 간단한 경우에는 혼합 할 수 있지만 그렇게하면 정적 검사 도구를 사용할 수 없음을 의미합니다 (또는 이러한 경고를 비활성화해야 함). 다른 버그가 발견되지 않을 수도 있습니다.
경우에 따라 선택의 여지가 없습니다. 메모리 관리 코드에서 size_t
유형의 값에 대한 산술을 수행 할 때.
int
에 충실 것, 그것이
main()
에 첫 번째 인수의 형태가 그대로
int
어쨌든 거기가 될 것입니다.
나쁘지 않습니다. 기호/불일치 불일치에 관한 컴파일러 경고를 수정합니다. 왜냐하면 나쁜 일은있을 법하지 않거나 불가능할 수도 있기 때문입니다. 서명 된/서명되지 않은 불일치 때문에 버그를 수정해야 할 때 컴파일러는 기본적으로 "내가 그렇게 말했어"라고 말합니다. 그 이유에 대한 경고를 무시하지 마십시오.
잘 속는 사람은 아니지만 어쨌든 읽을만한 가치가 있습니다. http://stackoverflow.com/questions/859943/c-how-can-i-fix-warnings-like-comparison-between-signed-and-unsigned – finnw