왜 C 컴파일러가 그렇게 적은가? 상당 부분을 차지하며 방대한 양의 새 코드에

C는 세계에서 가장 널리 사용되는 언어 중 하나입니다. 기존 코드의 상당 부분을 차지하며 방대한 양의 새 코드에 계속 사용됩니다. 그것은 사용자들에게 사랑 받고 있으며, C를 실행할 수 있다는 것은 많은 비공식적 인 플랫폼 정의에 대한 것으로 널리 알려져 있으며, 상대적으로 깨끗한 기능 세트를 가진 “작은”언어로 팬들에게 찬사를 보냅니다.

그렇다면 모든 컴파일러는 어디에 있습니까?

데스크탑에는 GCC와 Clang의 두 가지가 있습니다. 몇 초 동안 그것에 대해 생각하면 아마 인텔도 존재한다는 것을 기억할 것입니다. 소수의 다른 사람들도 있고, 보통 사람이 이름을 짓기가 너무 애매하고, 최근 언어 버전 (또는 종종 잘 정의 된 언어 하위 집합, “단일 하위 집합”)을 지원하기 위해 거의 보편적으로 귀찮게하지 않습니다. 이 목록의 구성원 중 절반 은 역사적 각주입니다. 나머지 대부분은 매우 전문화되어 있지만 실제로 전체 언어를 구현하지는 않습니다. 실제로 오픈 소스 인 것처럼 보이는 사람은 거의 없습니다.

팬들에게 사랑받는 다른 작은 언어 인 Scheme and Forth는 아마도 실제 사용자보다 더 많은 컴파일러를 가지고 있습니다. SML 과 같은 것조차도 C보다 선택해야 할 “심각한”구현이 있습니다. 검증을 목표로하는 새로운 (완료되지 않은) C 컴파일러 의 발표는 실제로 부정적인 반응을 보이며 베테랑 구현 은 충분히 기여할 수있는 충분한 기여를 얻기 위해 고군분투합니다. C99.

왜? C를 구현하는 것이 그렇게 어렵습니까? C ++이 아닙니다. 사용자는 그룹에 속하는 복잡성 그룹에 대해 매우 왜곡 된 아이디어를 가지고 있습니까 (예 : 실제로 Scheme보다 C ++에 더 가깝다는 것)?



답변

오늘, 당신이 될 겠다는 C 컴파일러를 필요로 최적화 컴파일러 , 특히 C 하드웨어에 가까운 언어가 더 이상이기 때문에 현재 때문에 프로세서 (믿을 수 없을만큼 복잡 밖으로의 순서 , 파이프 라인 , 슈퍼 스칼라 , 복합와 캐시TLB , 따라서 명령 스케줄링 등 이 필요 합니다 …). 오늘날의 x86 프로세서는 동일한 머신 코드를 실행할 수 있더라도 이전 세기의 i386 프로세서와 다릅니다. 참고 항목 C는 낮은 수준의 언어가 아닙니다 (컴퓨터가 빠른 PDP-11 아님) 데이비드 키스 넬에 의해 종이.

tinycc 또는 nwcc 와 같은 순진한 비 최적화 C 컴파일러를 사용하는 사람은 거의 없습니다 . 최적화 컴파일러가 제공 할 수있는 것보다 몇 배 느린 코드를 생성하기 때문입니다.

최적화 컴파일러를 코딩하는 것은 어렵습니다. GCC와 Clang은 모두 “원본 언어 중립적”코드 표현 (GCC의 경우 단순, Clang의 경우 LLVM)을 최적화하고 있습니다. 좋은 C 컴파일러의 복잡성은 파싱 단계에 있지 않습니다!

특히 C ++ 컴파일러를 만드는 것은 C 컴파일러를 만드는 것보다 훨씬 어렵지 않습니다 .C ++를 구문 분석하고이를 내부 코드 표현으로 변환하는 것은 복잡하지만 (C ++ 사양이 복잡하기 때문에) 이해하기 쉽지만 최적화 부분은 훨씬 더 많습니다. 복잡함 (GCC 내부 : 미들 엔드 최적화, 소스 언어 및 타겟 프로세서 중립적)은 대부분의 컴파일러를 구성하며 나머지는 여러 언어의 프런트 엔드와 여러 프로세서의 백 엔드간에 균형을 유지 합니다. 따라서 가장 최적화 된 C 컴파일러는 C ++, Fortran, D 등과 같은 다른 언어도 컴파일 할 수 있습니다. GCC의 C ++ 특정 부분은 컴파일러의 약 20 %입니다.

또한 C (또는 C ++)는 너무 널리 사용되어 사람들이 언어의 의미를 정확하게 정의하지 않는 공식 표준을 정확하게 따르지 않아도 코드를 컴파일 할 수 있기를 기대합니다 (따라서 각 컴파일러는 자체 해석을 할 수 있음) 그것의). CompCert에서 입증 한 C 컴파일러와 C의 보다 공식적인 의미론 을 다루는 Frama-C 정적 분석기 도 살펴보십시오 .

그리고 최적화는 긴 꼬리 현상입니다. 몇 가지 간단한 최적화를 구현하는 것은 쉽지만 컴파일러의 경쟁력을 높이지는 못합니다! 경쟁이 치열한 실제 컴파일러를 얻으려면 여러 가지 다양한 최적화를 구현하고이를 현명하게 구성하고 결합해야합니다. 즉, 실제 최적화 컴파일러는 복잡한 소프트웨어 여야합니다. BTW, GCC 및 Clang / LLVM에는 내부에 특수화 된 C / C ++ 코드 생성기가 여러 개 있습니다. 그리고 두 개발자 모두 대규모 개발자 커뮤니티 (수백 명, 주로 정규직 또는 최소 절반 이상)를 운영하는 거대한 짐승 (매년 수백만 개의 소스 코드, 매년 몇 퍼센트 씩 성장률)입니다.

이 없음을 알 수 없는 경우에도, 멀티 스레드 C 컴파일러 (내 지식의 최선을) 일부 (…, 명령 스케줄링 할당을 등록, 예를 들어 내부 절차 최적화) 컴파일러의 일부를 병렬로 실행할 수 있습니다. 그리고 병렬 빌드 make -j는 항상 충분하지는 않습니다 (특히 LTO 사용 ).

또한 C 컴파일러를 처음부터 코딩하는 데 어려움을 겪기 어렵고 이러한 노력은 몇 년 동안 지속되어야합니다. 마지막으로, 대부분의 C 또는 C ++ 컴파일러는 오늘날 무료 소프트웨어 (더 이상 스타트 업이 판매하는 새로운 독점 컴파일러 시장이 아님)이거나 최소한 독점적 인 상품 ( Microsoft Visual C ++ 과 같은 )이며, 자유 소프트웨어가되는 것은 컴파일러에 거의 필요합니다 ( 그들은 많은 다른 조직의 기여가 필요하기 때문에).

C 컴파일러에서 자유 소프트웨어로 처음부터 작업 할 수있는 자금을 얻게되어 기쁩니다. 그러나 오늘날 이것이 가능하다고 믿을만큼 순진하지 않습니다!


답변

C 구현의 수가 적다는 기본 가정에 이의를 제기하고 싶습니다.

나는 심지어 C를 모른다. 나는 C를 사용하지 않는다. 나는 C 공동체의 일원이 아니며, 심지어 언급 한 소수의 컴파일러보다 훨씬 더 많은 것을 알고있다.

무엇보다도 데스크톱에서 GCC와 Clang을 완전히 뒤 흔드는 컴파일러가 있습니다 : Microsoft Visual C 이전의 전통적인 데스크톱 사용자와는 달리 Windows는 여전히 지배적 인 데스크톱 OS이며 대부분의 Windows 데스크톱 C 프로그램은 Microsoft 도구를 사용하여 컴파일 될 수 있습니다.

전통적으로 모든 OS 공급 업체와 모든 칩 공급 업체에는 자체 컴파일러가있었습니다. OS 벤더 인 Microsoft는 Microsoft Visual C를 보유하고 있습니다. OS 벤더 및 칩 벤더 인 IBM은 XLC (AIX의 기본 시스템 컴파일러이며 AIX 및 i / OS가 모두 컴파일 된 컴파일러)를 가지고 있습니다. . 인텔에는 자체 컴파일러가 있습니다. Sun / Oracle에는 Sun Studio에 자체 컴파일러가 있습니다.

그런 다음 PathScale 및 Portland Group과 같은 고성능 컴파일러 공급 업체가 있습니다.이 공급 업체는 컴파일러 (및 OpenMP 라이브러리)를 번호 처리에 사용합니다.

디지털 화성은 여전히 ​​사업에 종사하고 있습니다. 월터 브라이트는 지구상에서 유일하게 생산 품질의 C ++ 컴파일러 (대부분)를 스스로 만들었습니다.

마지막으로 임베디드 마이크로 컨트롤러 용 독점 컴파일러가 모두 있습니다. IIRC는 매년 데스크탑, 모바일, 서버, 워크 스테이션 및 메인 프레임 CPU가 컴퓨팅 역사 전체에 판매 된 것보다 더 많은 마이크로 컨트롤러를 판매하고 있습니다. 따라서 이들은 틈새 제품이 아닙니다 .

Truffle AST 인터프리터 프레임 워크를 사용하여 작성된 JVM (!)에서 실행 되는 C 인터프리터 (!) 인 TruffleC 에 대해서는 GCC 및 Clang (특정 벤치 마크에서 가장 빠른 것)보다 7 % 느리게 언급 된 TruffleC 가 있습니다. 컴퓨터 언어 벤치마킹 게임으로 마이크로 벤치 마크보다 빠릅니다. TruffleC를 사용하여 Truffle 팀은 실제 C Ruby 구현보다 Ruby C 확장을 더 빨리 실행하기 위해 JRuby + Truffle 버전을 얻을 수있었습니다!

그래서 이것들은 C에 대해 전혀 알지 않고도 머리 꼭대기에서 이름을 지정할 수있는 나열된 것 외에도 6 가지 구현입니다.


답변

몇 개의 컴파일러가 필요합니까?

기능 세트가 다른 경우 이식성 문제가 발생합니다. 그들이 상품화되어 있다면 “default”(GCC, Clang 또는 VS)를 선택하십시오. 마지막 5 % 성능에 관심이있는 경우 벤치 마크가 해제됩니다.

레크리에이션 또는 연구 목적으로 프로그래밍 언어 작업을 수행하는 경우보다 현대적인 언어 일 수 있습니다. 따라서 Scheme 및 ML에 대한 장난감 컴파일러의 확산. 비록 OCaml이 장난감이 아닌 비 학술적 사용에 대한 견인력을 얻는 것처럼 보이지만.

이것은 언어마다 많이 다릅니다. Java에는 본질적으로 Sun / Oracle 툴체인과 GNU가 있습니다. 파이썬에는 표준 해석기와 비교할 때 실제로 존중되지 않는 다양한 컴파일러가 있습니다. Rust와 Go는 각각 정확히 하나의 구현을가집니다. C #에는 Microsoft와 Mono가 있습니다.


답변

C / C ++는 3 가지 주요 공통 사양 구현이 있다는 점에서 컴파일 된 언어 중에서 독특합니다.

많이 사용되지 않는 것을 무시하는 규칙에 따라 다른 모든 컴파일 언어에는 0에서 1이 있습니다.

그리고 나는 자바 스크립트가 ‘컴파일’을 지정 해야하는 유일한 이유라고 생각합니다.


답변

그래서 당신의 목표 언어는 무엇입니까?

SML 컴파일러는 종종 C 또는 LLVM과 같은 (또는 링크, JVM 또는 JavaScript에서 볼 수있는) 대상을 지정합니다.

C를 컴파일하는 경우 JVM으로 이동하기 때문이 아닙니다. 당신은 C보다 더 나쁜 것에 갈 것입니다. 훨씬 더 나쁩니다. 그런 다음 모든 대상 플랫폼에 대해 사소한 지옥을 여러 번 복제합니다.

그리고 C는 C ++이 아니지만 Scheme보다 C ++에 더 가깝다고 말하고 싶습니다. 정의되지 않은 동작 악의 자체 하위 집합이 있습니다 (내장 유형의 크기를보고 있습니다). 그리고 그 미세한 부분을 망가 뜨리거나 (또는 ​​”정확하게”그러나 예기치 않게 수행한다면) 당신은 얼마나 끔찍한지를 알려주는 중요한 시스템에 수십 개의 기존 코드를 가지고 있습니다. 당신이 SML 컴파일러를 망치는 경우, 그냥 작동하지 않습니다 – 누군가는 수도 알 수 있습니다. 언젠가