가장 음의 int 값이 모호한 함수 오버로드에 대한 오류를 일으키는 이유는 무엇입니까?
나는 C ++에서 함수 오버로딩에 대해 배우고 있는데 이것을 발견했습니다.
void display(int a)
{
cout << "int" << endl;
}
void display(unsigned a)
{
cout << "unsigned" << endl;
}
int main()
{
int i = -2147483648;
cout << i << endl; //will display -2147483648
display(-2147483648);
}
내가 이해 한 바에 따르면 int
범위 (제 경우 int
에는 4 바이트) 에 제공된 모든 값 이 호출 display(int)
되고이 범위를 벗어난 값은 모호합니다 (컴파일러가 호출 할 함수를 결정할 수 없기 때문에). int
최소값을 제외한 전체 값 범위에 대해 유효합니다. 즉 -2147483648
컴파일이 오류와 함께 실패하는 경우
과부하 호출
display(long int)
이 모호합니다.
그러나 동일한 값을 an에 취하고 값을 int
인쇄하면 2147483648
. 나는이 행동과 문자 그대로 혼동된다.
이 동작은 가장 많은 음수가 전달 될 때만 관찰되는 이유는 무엇입니까? ( 사실 음수와 양수가 동일한 이진 표현을 갖는 경우에 a short
와 함께 사용되는 경우 동작은 동일합니다. -32768
)
사용 된 컴파일러 : g ++ (GCC) 4.8.5
이것은 매우 미묘한 오류입니다. 지금보고있는 것은 C ++에 음의 정수 리터럴이 없기 때문입니다. [lex.icon]을 보면 정수 리터럴을 얻습니다 .
정수 리터럴
10 진수 리터럴 정수 접미사 opt
[...]
10 진수 리터럴 일 수 있습니다.
decimal-literal :
0이 아닌
10 진수 리터럴 ' opt digit
여기서 자리 이다 [0-9]
및 0이 아닌 숫자는 이다 [1-9]
접미사 파 중 하나 일 수있다 u
, U
, l
, L
, ll
, 또는 LL
. 여기 어디에도 -
십진 리터럴의 일부가 포함 되어 있지 않습니다 .
§2.13.2에는 다음도 포함됩니다.
정수 리터럴은 그 값을 결정할 때 무시됩니다 선택적 분리 따옴표로, 어떤 기간 또는 지수 부분이없는 숫자의 순서입니다. 정수 리터럴에는 기준을 지정하는 접두사와 해당 유형을 지정하는 접미사가있을 수 있습니다. 숫자 시퀀스의 어휘 첫 번째 숫자가 가장 중요합니다. 진수 정수 리터럴 (베이스 열)는 0이 아닌 숫자로 시작 및 십진수의 시퀀스로 구성된다.
(강조 내)
이는 -
in -2147483648
이 단항 임을 의미합니다 operator -
. 즉, -2147483648
실제로 -1 * (2147483648)
. 2147483648
하나가 너무 많기 때문에 int
a로 승격되고 long int
모호성은 일치하지 않는 것에서 비롯됩니다.
이식 가능한 방식으로 유형의 최소 또는 최대 값을 얻으려면 다음을 사용할 수 있습니다.
std::numeric_limits<type>::min(); // or max()
표현식 -2147483648
은 실제로 -
연산자를 상수에 적용합니다 2147483648
. 플랫폼에서 int
저장할 수 없으며 2147483648
더 큰 유형으로 표시되어야합니다. 따라서 표현 -2147483648
으로 추론되지 않은 signed int
, 그러나 더 큰 유형을 체결했다 signed long int
.
long
컴파일러에 대한 오버로드를 제공하지 않기 때문에 똑같이 유효한 두 오버로드 중에서 선택해야합니다. 컴파일러는 모호한 오버로드에 대한 컴파일러 오류를 발행해야합니다.
타인의 답변 확대
OP가 혼란스러운 이유를 명확히하기 위해 먼저 아래 의 signed int
이진 표현을 고려하십시오 2147483647
.
다음으로,이 번호에 1을 추가 : 또 다른주기 signed int
의 -2147483648
(영업 이익이 사용하고자하는)
마지막으로 , OP가 -2147483648
a long int
대신 a로 컴파일 될 때 왜 혼란스러워 지는지 알 수 있습니다 signed int
. 32 비트에 확실히 들어 맞기 때문입니다.
현재 답변들을 언급하지만, 단항 연산자 ( -
)인가 이후 해결 2147483648
을 인 long int
32 비트에 맞지 않는다.
'developer tip' 카테고리의 다른 글
전송 인코딩 : gzip 대 콘텐츠 인코딩 : gzip (0) | 2020.09.10 |
---|---|
엔티티 프레임 워크를 사용하여 ID로 객체를 삭제하는 방법 (0) | 2020.09.09 |
Bash 백틱에 해당하는 일괄 처리 (0) | 2020.09.09 |
만드는 방법 (0) | 2020.09.09 |
fs.writeFileSync를 사용하여 JSON 파일에 JSON 객체 쓰기 (0) | 2020.09.09 |