long double x = 8.99999999999999999
의 경우 값은 'L'이 추가되지 않으므로 double
으로 저장됩니다. x
변수를 float 유형 long double
으로 이미 선언 한 경우 C 컴파일러에서 형식 유추를 수행 할 수없는 이유는 무엇입니까?C 컴파일러가 형식 유추를 수행 할 수없는 이유는 무엇입니까?
답변
C가 형식이 아닌 안전이기 때문에 C 컴파일러는 형식 유추를 수행하지 않습니다. 당신은 쉽게 무의미한 것, 무효화 된 포인터, 되돌아 오는 것을 쉽게 캐스팅 할 수 있습니다. 그것은 규칙에 위배되지 않습니다. 이것은 최소한 C에 대한 어떤 타입의 타입 추론도 근사치 일 뿐이라는 것을 의미하며, 컴파일러가 여러분의 타입에 무엇이 잘못되었는지에 대한 단서를 제공 할 것입니다.
C가 타입 유추를 수행하지 않는 이유는 다음과 같습니다. C 타입은 이 아니고 논리적 관계를 시행하거나 언어에서 진실을 인코딩하기위한 것이 아닙니다. 어떤 레벨에서, 사운드 타입 시스템 (Haskell, OCaml, SML, Coq 등)을 가진 언어는 이이라고 당신에게 말합니다 : 타입으로부터 당신의 프로그램에 대해 적어 놓을 수있는 정리가 있습니다. (Philip Wadler의 "Theorem 's for Free!"에 대한 흥미로운 예제를보십시오!)
그렇다면 왜 은 C 타입을 사용합니까? 그 이유는 순전히 컴파일러가 어떤 수준에서는 메모리에 저장된대로 데이터를 구성하는 방법을 알아야한다는 것입니다. 논리적 인 일관성 대신에 C 타입은 물건 배열 방법을 알려주는 고기입니다. 구조체 내에서이 int를 어디에 놓아야합니까?
대신에 C는 에 이디엄 번호를 사용합니다. more 유형 안전한 언어의 표준 기능 예를 들어 void 포인터는 대개 매개 변수형 다형성을 나타 내기 위해 사용됩니다. (예를 들어, 모든 데이터 유형에 대한 포인터를 포함 할 수있는 목록을 가질 수 있습니다.) 사실 C에서 다른 데이터 유형을 가리키는 목록을 인코딩 할 수 있습니다. 전통적인 함수형 언어에서리스트의 유도 형은 모든 엘리먼트가 같은 타입이어야한다. C에서는 inerection 타입과 행을 쉽게 인코딩 할 수있다. (예를 들어, C에서리스트 엘리먼트에 식별자로 태그를 붙인다.)
이 종류와 C의 메모리 안전 방언, 어떤 장소에서, 다형성 는 아직도의 미묘한의 당신이 많은 제공하면서 무효 포인터 같은 것들의 발생을 대체 않습니다 예를 들어, 같은 Cyclone를 볼 수 있습니다 C 언어.
long double x = 3.0 인 경우. 값 3.0은 double로 저장됩니다.
사실이 아닙니다. 그러면 3.0이 long double
으로 저장됩니다.
당신이 맞습니다. 나는 다른 가치를 지니고 있습니다. 편집 된 질문 ... – KawaiKx
the C standard 표준에서 명시 적으로 this가 이 아니고이 아니기 때문에 컴파일러에서 형식 유추를 수행하지 않습니다. 부동 상수에
제 6.4.4.2는 말한다 :
unsuf Fi를 고정 된 플로리다 oating 일정을 두 번 입력합니다. 문자 f 또는 F로 끝나는 경우 float 유형입니다. 문자 l 또는 l을 접미사로 붙이면 long double 유형을 갖습니다.
왜 표준 그렇게 말하는가? 어쩌면 컴파일러를 단순화하기 때문에 (솔직히 말하면, 나는 모른다).
C 언어가 처음 개발되었을 때 1970 년대 초, 컴파일러를 실행하는 컴퓨터는 메모리가 거의 없었지만 느리게 실행되었습니다. 이 때문에 컴파일러가 간단 할 수 있도록 언어를 디자인해야 컴파일이 빠를 수 있습니다. 간단한 컴파일러는 컴파일러가 추론 할 필요가있을 때마다 CPU와 메모리를 사용하기 때문에 프로그래머가 모든 것을 알 필요가 있습니다.
또 다른 이유는 똑같이 중요한 이유는 처음에 C를 개발하고 사용하는 사람들이 처음에는 운영 체제를 작성했기 때문에 영리하지 않으려 고하는 언어를 원했습니다. 운영 체제를 작성하는 것은 컴파일러가 수행 할 수도 있고 수행하지 않을 작업을 추측 할 필요없이 까다 롭습니다. 어떤 일이 발생하는지에 대한 정확한 제어가 필요하고 단순한 언어가 그 의미에서 운영 체제 작성자에게 커다란 이점이 될 수 있습니다.
이러한 이유로 인해 C는 이후 수십 년 동안 고안된 고급 언어가 이제 응용 프로그램 프로그래밍을 목표로했던 많은 기능없이 끝났습니다. 객체 지향, 유형 유추, 가비지 콜렉션, 예외 없음 및 스레딩 지원이 없습니다.
미래에는 C가 그런 것들을 가지기 위해 변경 될 수도 있습니다 (사실 최신 C 표준은 현재 네이티브 스레드를 가지지 만 선택 사항이라고 생각합니다). 그러나 전체적으로, 너는 다른 언어를 원해. 선택할 수있는 문자 그대로 수천 개의 재미있는 언어가 있습니다.
이것은 모두 추측입니다.우리가 알고있는 전부는 데니스 리치 (Dennis Ritchie)가 BCPL 전통을 토대로 언어를 그렇게 설계 한 것입니다. 또 다른 설명은 Ritchie가 실제로 컴파일러 작가가 아니었고 그 당시에 각을 두려워하는 곳으로 가기를 주저했다는 것입니다. – EJP
다른 사람들은 표준 상태 that unless suffixed, a floating point constant is a double
을 언급 했으므로. 이제는 계산상의 복잡성으로 인해 배후의 논리를 살펴보십시오. 또한 표준은 a가 long double>=double
이라고 가정하고 이제는 sizeof(double)=8
과 sizeof(long double)=16
이라는 시스템을 생각해보십시오. 이제는 특별한 예가 있는데, 접미사가없는 경우 컴파일러는 64-bit
정밀도 부동 소수점 수를 계산하고 나머지 8 바이트를 제로화해야합니다. 그러나 제안 할 때 형식 유추를 수행하는 경우 이제 계산을 수행하여 128-bit
부동 소수점 수를 산출해야합니다.
그리고 converting a floating point number into binary 표현은 쉬운 작업이 아니므로 컴파일러는 가능한 한 인색 해 보려고합니다. 특히이 예에서는 8.99999999999999999
을 long double
으로 업그레이드 할 필요가 없으므로 정확한 정확도로 double
으로 압축 할 수 있습니다.
기울임 꼴로 표시된 문장 정보 : 사실은 아닙니다. # 1) 나는 이것에 관해서 표준에 아무것도 보이지 않는다. # 2) GCC의 복사본에서 'double'변수에 맞지 않는 거대한 부동 소수점 상수를 할당하면 'inf'로 인쇄됩니다. 표준이 말했듯이, 상수에 'L'접미사를 붙이면 변수에 올바르게 저장됩니다. – ArjunShankar
@ArjunShankar 시스템에서 double과 long double의 크기가 같은지 확인 했습니까? 나는 double double이 double보다 큰 시스템을 추천하고 있습니까? –
예. 확인했습니다. 그리고 그들은 같은 것이 아닙니다. – ArjunShankar
표준 C 사양에서는 형식 유추를해서는 안된다고 말합니다. * Ocaml *, * Haskell * 또는 * C++ 11 * 언어 유 형을 참조하십시오. –
@BasileStarynkevitch : 당신은 대답으로 그것을 넣을 수 있습니다. – kay
타입을 이미 선언했을 때 추론 할 사항은 무엇입니까? – Dikei