부호있는 / 부호없는 비교
다음 코드가 표시된 장소에서 경고를 표시하지 않는 이유를 이해하려고합니다.
//from limits.h
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
/* = 0x7fffffff */
int a = INT_MAX;
//_int64 a = INT_MAX; // makes all warnings go away
unsigned int b = UINT_MAX;
bool c = false;
if(a < b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a > b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a <= b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a >= b) // warning C4018: '<' : signed/unsigned mismatch
c = true;
if(a == b) // no warning <--- warning expected here
c = true;
if(((unsigned int)a) == b) // no warning (as expected)
c = true;
if(a == ((int)b)) // no warning (as expected)
c = true;
배경 홍보와 관련이 있다고 생각했는데 마지막 두 사람은 그렇지 않은 것 같습니다.
내 생각에, 첫 번째 ==
비교는 다른 것만 큼 서명 / 부호없는 불일치입니까?
부호있는 값과 부호없는 값을 비교할 때 컴파일러는 부호있는 값을 부호없는 값으로 변환합니다. 평등을 위해 이것은 중요하지 않습니다 -1 == (unsigned) -1
. 다른 비교의 경우 중요합니다. 예를 들어 다음이 참 -1 > 2U
입니다..
편집 : 참조 :
5/9 : (표현식)
산술 또는 열거 유형의 피연산자를 예상하는 많은 이항 연산자는 유사한 방식으로 변환을 일으키고 결과 유형을 산출합니다. 목적은 결과의 유형이기도 한 공통 유형을 생성하는 것입니다. 이 패턴을 일반적인 산술 변환이라고하며 다음과 같이 정의됩니다.
피연산자가 long double 유형이면 다른 피연산자는 long double로 변환됩니다.
그렇지 않으면 피연산자가 double이면 다른 피연산자가 double로 변환됩니다.
그렇지 않으면 피연산자가 float이면 다른 피연산자는 float로 변환됩니다.
그렇지 않으면 적분 프로모션 (4.5)이 두 피연산자 모두에서 수행됩니다 .54)
그런 다음 피연산자가 unsigned long이면 다른 피연산자는 unsigned long으로 변환됩니다.
그렇지 않고 한 피연산자가 long int이고 다른 하나는 unsigned int이면 long int가 unsigned int의 모든 값을 나타낼 수 있으면 unsigned int는 long int로 변환됩니다. 그렇지 않으면 두 피연산자가 unsigned long int로 변환됩니다.
그렇지 않으면 피연산자가 길면 다른 피연산자가 long으로 변환됩니다.
그렇지 않으면 피연산자가 부호가 없으면 다른 피연산자가 부호 없음으로 변환됩니다.
4.7 / 2 : (통합 변환)
대상 유형이 부호없는 경우 결과 값은 소스 정수에 합동하는 최소 부호없는 정수입니다 (모듈로 2 n 여기서 n은 부호없는 유형을 나타내는 데 사용되는 비트 수). [참고 : 2의 보수 표현에서이 변환은 개념적이며 비트 패턴에 변화가 없습니다 (잘림이없는 경우). ]
EDIT2 : MSVC 경고 수준
What is warned about on the different warning levels of MSVC is, of course, choices made by the developers. As I see it, their choices in relation to signed/unsigned equality vs greater/less comparisons make sense, this is entirely subjective of course:
-1 == -1
means the same as -1 == (unsigned) -1
- I find that an intuitive result.
-1 < 2
does not mean the same as -1 < (unsigned) 2
- This is less intuitive at first glance, and IMO deserves an "earlier" warning.
Why signed/unsigned warnings are important and programmers must pay heed to them, is demonstrated by the following example.
Guess the output of this code?
#include <iostream>
int main() {
int i = -1;
unsigned int j = 1;
if ( i < j )
std::cout << " i is less than j";
else
std::cout << " i is greater than j";
return 0;
}
Output:
i is greater than j
Surprised? Online Demo : http://www.ideone.com/5iCxY
Bottomline: in comparison, if one operand is unsigned
, then the other operand is implicitly converted into unsigned
if its type is signed!
The == operator just does a bitwise comparison (by simple division to see if it is 0).
The smaller/bigger than comparisons rely much more on the sign of the number.
4 bit Example:
1111 = 15 ? or -1 ?
so if you have 1111 < 0001 ... it's ambiguous...
but if you have 1111 == 1111 ... It's the same thing although you didn't mean it to be.
In a system that represents the values using 2-complement (most modern processors) they are equal even in their binary form. This may be why compiler doesn't complain about a == b.
And to me it's strange compiler doesn't warn you on a == ((int)b). I think it should give you an integer truncation warning or something.
참고URL : https://stackoverflow.com/questions/5416414/signed-unsigned-comparisons
'IT TIP' 카테고리의 다른 글
\ R이 Java 8과 Java 9의 정규식에서 다르게 작동하는 이유는 무엇입니까? (0) | 2020.10.14 |
---|---|
생성자 경고에서 이것을 누출 (0) | 2020.10.14 |
__weak 참조와 __block 참조의 차이점은 무엇입니까? (0) | 2020.10.14 |
TypeScript에서 "type"예약어는 무엇입니까? (0) | 2020.10.14 |
pushState 및 SEO (0) | 2020.10.14 |