기본적으로 int가 아닌 정수 리터럴 유형?
저는 방금 이 질문에 답했습니다. 이 질문은 for 루프에서 100억까지 반복하는 것이 10억까지 반복하는 것보다 왜 그렇게 오래 걸리느냐는 질문이었습니다.
for (i = 0; i < 10000000000; i++)
저와 다른 많은 사람들의 분명한 대답은 반복 변수가 32비트(100억에 도달하지 않음)이고 루프가 무한 루프를 얻기 때문이라는 것이었습니다.
하지만 저는 이 문제를 깨달았지만, 여전히 컴파일러 내부에서 실제로 무슨 일이 일어나고 있는지 궁금합니다.
리터럴에 다음이 추가되지 않았기 때문입니다.L
는 IMHO 타입이어야 .int
32비트도 마찬가지입니다.따라서 오버플로로 인해 정상이어야 합니다.int
도달할 수 있는 범위 내에 있습니다.에서 도달할 수 없다는 것을 실제로 인식하는 것.int
컴파일러는 그것이 100억이라는 것을 알아야 하며 따라서 그것을 32비트 이상의 상수로 보아야 합니다.
(이에는 적어도 됩니까?L
그리고 이것이 표준적인 행동입니까?아니면 오버플로(정수 오버플로가 실제로는 UB인가)로 인해 UB와 같은 배후에서 뭔가 다른 일이 일어나고 있습니까?이 기준서의 일부 인용문이 있으면 좋을 수도 있습니다.
원래 질문은 C였지만, C++ 답변도 감사합니다.
C++에 관한 한:
C++11, [lex.icon] 2
정수 리터럴의 유형은 표 6에서 해당 값을 나타낼 수 있는 목록 중 첫 번째입니다.
그리고 표 6은 접미사와 십진 상수가 없는 리터럴의 경우 다음을 제공합니다.
int
long int
long long int
또는 의 경우에도 (16진수, 16진수 8진수)unsigned
형식은 허용되지만 각 형식은 목록에서 해당 서명된 형식 다음에 옵니다.)
그래서, 그 경우에 상수는 다음과 같이 해석된 것이 분명합니다.long int
(또는)long long int
한다면long int
너무 32비트였습니다.).
"너무 큰 리터럴"은 컴파일 오류를 초래합니다.
프로그램의 변환 단위 중 하나에 허용된 형식으로 나타낼 수 없는 정수 리터럴이 포함된 경우 프로그램의 형식이 잘못되었습니다.
(ibidem, 3)
이 샘플에서 즉시 확인할 수 있으며, 이는 ideone.com 이 32비트 컴파일러를 사용한다는 것을 상기시킵니다.
C에 대한 질문이었는데... 뭐, 거의 비슷하네요.
C99, § 6.4.4.1
정수 상수의 유형은 해당 값이 표시될 수 있는 목록 중 첫 번째입니다.
C++ 표준과 동일한 목록입니다.
부록: C99와 C++11 모두 리터럴이 다른 모든 것이 실패할 경우 "확장 정수 유형"(즉, 다른 구현 특정 정수 유형)이 되도록 허용합니다. (C++11, [lex.icon] 3; C99, 표 뒤에 § 6.4.4.15)
ISO/IEC 9899라는 라벨이 붙은 C 표준 초안에서:TC2 위원회 초안 — 2005년 5월 6일, 규칙은 Matteo가 발견한 C++ 규칙과 매우 유사합니다.
5 정수 상수의 유형은 그 값이 표현될 수 있는 해당 목록의 첫 번째입니다.
Suffix Decimal Constant Octal or Hexadecimal Constant
-------------------------------------------------------------------
none int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
u or U unsigned int unsigned int
unsigned long int unsigned long int
unsigned long long int unsigned long long int
l or L long int long int
long long int unsigned long int
long long int
unsigned long long int
Both u or U unsigned long int unsigned long int
and l or L unsigned long long int unsigned long long int
ll or LL long long int long long int
unsigned long long int
Both u or U unsigned long long int unsigned long long int
and ll or LL
나는 여전히 컴파일러 내부에서 실제로 무슨 일이 일어나고 있었는지 궁금합니다.
컴파일러가 코드를 해석하는 방법에 관심이 있다면 어셈블리어를 볼 수 있습니다.
10000000000:
400054f:
mov -0x4(%rbp),%eax
mov %eax,-0x8(%rbp)
addl $0x1,-0x4(%rbp)
jmp 40054f <main+0xb>
그래서 10000000000을 1000000으로 바꾸면 무한 루프로 컴파일했습니다.
....
test %al,%al
jne 400551
언급URL : https://stackoverflow.com/questions/8108642/type-of-integer-literals-not-int-by-default
'code' 카테고리의 다른 글
인수가 있는 함수에서 Invoke-Command-ScriptBlock 사용 (0) | 2023.08.26 |
---|---|
Ansible MariaDB 10.1.47 암호가 강제되지 않음 (0) | 2023.08.26 |
Python에서 목록을 "멋지게" 인쇄하는 방법 (0) | 2023.08.26 |
MSDeploy(Visual Studio)에서 App_Data 폴더를 삭제하지 않고 다른 모든 폴더를 삭제하도록 합니다. (0) | 2023.08.26 |
PowerShell의 URL에서 도메인 가져오기 (0) | 2023.08.26 |