2012-04-06 3 views
3

long double x = 8.99999999999999999의 경우 값은 'L'이 추가되지 않으므로 double으로 저장됩니다. x 변수를 float 유형 long double으로 이미 선언 한 경우 C 컴파일러에서 형식 유추를 수행 할 수없는 이유는 무엇입니까?C 컴파일러가 형식 유추를 수행 할 수없는 이유는 무엇입니까?

+5

표준 C 사양에서는 형식 유추를해서는 안된다고 말합니다. * Ocaml *, * Haskell * 또는 * C++ 11 * 언어 유 형을 참조하십시오. –

+0

@BasileStarynkevitch : 당신은 대답으로 그것을 넣을 수 있습니다. – kay

+0

타입을 이미 선언했을 때 추론 할 사항은 무엇입니까? – Dikei

답변

2

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 언어.

1

long double x = 3.0 인 경우. 값 3.0은 double로 저장됩니다.

사실이 아닙니다. 그러면 3.0이 long double으로 저장됩니다.

+0

당신이 맞습니다. 나는 다른 가치를 지니고 있습니다. 편집 된 질문 ... – KawaiKx

4

the C standard 표준에서 명시 적으로 this가 이 아니고이 아니기 때문에 컴파일러에서 형식 유추를 수행하지 않습니다. 부동 상수에

제 6.4.4.2는 말한다 :

unsuf Fi를 고정 된 플로리다 oating 일정을 두 번 입력합니다. 문자 f 또는 F로 끝나는 경우 float 유형입니다. 문자 l 또는 l을 접미사로 붙이면 long double 유형을 갖습니다.


표준 그렇게 말하는가? 어쩌면 컴파일러를 단순화하기 때문에 (솔직히 말하면, 나는 모른다).

4

C 언어가 처음 개발되었을 때 1970 년대 초, 컴파일러를 실행하는 컴퓨터는 메모리가 거의 없었지만 느리게 실행되었습니다. 이 때문에 컴파일러가 간단 할 수 있도록 언어를 디자인해야 컴파일이 빠를 수 있습니다. 간단한 컴파일러는 컴파일러가 추론 할 필요가있을 때마다 CPU와 메모리를 사용하기 때문에 프로그래머가 모든 것을 알 필요가 있습니다.

또 다른 이유는 똑같이 중요한 이유는 처음에 C를 개발하고 사용하는 사람들이 처음에는 운영 체제를 작성했기 때문에 영리하지 않으려 고하는 언어를 원했습니다. 운영 체제를 작성하는 것은 컴파일러가 수행 할 수도 있고 수행하지 않을 작업을 추측 할 필요없이 까다 롭습니다. 어떤 일이 발생하는지에 대한 정확한 제어가 필요하고 단순한 언어가 그 의미에서 운영 체제 작성자에게 커다란 이점이 될 수 있습니다.

이러한 이유로 인해 C는 이후 수십 년 동안 고안된 고급 언어가 이제 응용 프로그램 프로그래밍을 목표로했던 많은 기능없이 끝났습니다. 객체 지향, 유형 유추, 가비지 콜렉션, 예외 없음 및 스레딩 지원이 없습니다.

미래에는 C가 그런 것들을 가지기 위해 변경 될 수도 있습니다 (사실 최신 C 표준은 현재 네이티브 스레드를 가지지 만 선택 사항이라고 생각합니다). 그러나 전체적으로, 너는 다른 언어를 원해. 선택할 수있는 문자 그대로 수천 개의 재미있는 언어가 있습니다.

+2

이것은 모두 추측입니다.우리가 알고있는 전부는 데니스 리치 (Dennis Ritchie)가 BCPL 전통을 토대로 언어를 그렇게 설계 한 것입니다. 또 다른 설명은 Ritchie가 실제로 컴파일러 작가가 아니었고 그 당시에 각을 두려워하는 곳으로 가기를 주저했다는 것입니다. – EJP

1

다른 사람들은 표준 상태 that unless suffixed, a floating point constant is a double을 언급 했으므로. 이제는 계산상의 복잡성으로 인해 배후의 논리를 살펴보십시오. 또한 표준은 a가 long double>=double이라고 가정하고 이제는 sizeof(double)=8sizeof(long double)=16이라는 시스템을 생각해보십시오. 이제는 특별한 예가 있는데, 접미사가없는 경우 컴파일러는 64-bit 정밀도 부동 소수점 수를 계산하고 나머지 8 바이트를 제로화해야합니다. 그러나 제안 할 때 형식 유추를 수행하는 경우 이제 계산을 수행하여 128-bit 부동 소수점 수를 산출해야합니다.

그리고 converting a floating point number into binary 표현은 쉬운 작업이 아니므로 컴파일러는 가능한 한 인색 해 보려고합니다. 특히이 예에서는 8.99999999999999999long double으로 업그레이드 할 필요가 없으므로 정확한 정확도로 double으로 압축 할 수 있습니다.

+0

기울임 꼴로 표시된 문장 정보 : 사실은 아닙니다. # 1) 나는 이것에 관해서 표준에 아무것도 보이지 않는다. # 2) GCC의 복사본에서 'double'변수에 맞지 않는 거대한 부동 소수점 상수를 할당하면 'inf'로 인쇄됩니다. 표준이 말했듯이, 상수에 'L'접미사를 붙이면 변수에 올바르게 저장됩니다. – ArjunShankar

+0

@ArjunShankar 시스템에서 double과 long double의 크기가 같은지 확인 했습니까? 나는 double double이 double보다 큰 시스템을 추천하고 있습니까? –

+0

예. 확인했습니다. 그리고 그들은 같은 것이 아닙니다. – ArjunShankar