첫 번째 C ++ 컴파일러는 어떻게 C ++로 작성 될 수 있습니까?


48

Stroustrup은 최초의 C ++ 컴파일러 인 Cfront가 C ++ ( Stroustrup FAQ ) 로 작성되었다고 주장합니다 .

그러나 첫 번째 C ++ 컴파일러를 C ++로 작성하는 방법은 무엇입니까?

컴파일러를 구성하는 코드도 컴파일해야하므로 첫 번째 C ++ 컴파일러를 C ++로 작성할 수 없었습니까?


6
en.wikipedia.org/wiki/Cfront 는이 문제를 약간 다룹니다.
christofr

답변:


57

열쇠는 바로 여기 있습니다 :

첫 번째 C ++ 컴파일러 (Cfront)는 C ++로 작성되었습니다. 이를 구축하기 위해 먼저 C를 사용하여 "C를 사용하여 클래스"-C 전처리기를 작성했습니다. "C with Classes"는 C ++의 직접적인 조상이 된 C 방언이었습니다. 이 전처리 기는 "C with Classes"구문 (예 : 클래스 및 생성자)을 C로 변환했습니다. 모든 언어를 이해하지 못하고 C 컴파일러가 수행 할 수있는 유형 검사를 대부분 남겨두고 개별을 번역 한 전통적인 전 처리기였습니다. 완전한 지식이없는 구조. 그런 다음 "C with Classes"에 Cfront의 첫 번째 버전을 작성했습니다.

따라서 Cfront의 첫 번째 버전은 C ++로 작성된 것이 아니라 중간 언어로 작성되었습니다. C에서 직접 C 컴파일러와 전처리기를 만들 수있는 기능으로 인해 C의 많은 혁신 (및 방대한 보안 허점 )이 발생했습니다. 따라서 C 클래스를 사용할 수 있기 때문에 "C with Classes"코드를 직선 C로 바꾸는 새로운 전임자를 작성하십시오. 그런 다음 "C with Classes"를 사용하여 C ++ 컴파일러를 작성하십시오 (C에서 할 수는 없지만 잠시 시간이 걸릴 것입니다).이 C ++ 컴파일러를 사용하여보다 효율적이고 완전한 컴파일러를 작성하십시오. C ++. 알았다?


5
내가 할 수있는 일 중 가장 좋아하는 이야기 중 하나에 대한 링크를 포함하여 +1합니다.
jwernerny

3
컴파일러는 유효한 C ++ 코드로 작성되었지만 "C with Classes"프리 프로세서에서 지원하는 일부 C ++ 기능 만 사용했습니다. 전체 언어의 하위 집합을 사용했기 때문에 결과 (Cfront의 첫 번째 작업 버전)에서도 컴파일되었습니다. 이 "부트 스트랩"단계를 수행 한 후에는 전처리기를 다시 사용할 필요가 없었을 것입니다.
joeytwiddle

2
@jwernerny-나는 항상 그 기사가 만족스럽지 않다는 것을 알았습니다. 그는 가장 어려운 아닌 사소한 부분 얼버무 : "버그는 UNIX '로그인'명령 코드를 일치합니다 그것이 의도 된 암호화 된 암호 또는 특정 알려진 암호 중 하나를 받아 들일 수 있도록 대체 코드는 로그인 명령을 miscompile 것입니다.. " 그러나 이것이 어떻게 이루어질까요? 실제로 증명 된 적이 있습니까?
detly

3
"C의 많은 혁신 (그리고 방대한 보안 허점)에 이르렀다": 내가 아는 한이 트릭은 C뿐만 아니라 어떤 언어로도 사용될 수있다. 따라서 다른 언어도 같은 보안 허점을 가질 수있다.
조르지오

2
@detly : 지금은 사소한 것처럼 들리지만 1983 년에는 구현 다양성이 부족하여 가능한 새로운 공격이었습니다. 소스에서 모든 것을 컴파일하는 것이 지금보다 훨씬 더 큰 시련이기 때문에 우리는 그 당시 바이너리를 더 신뢰했습니다.
Blrfl

17

부트 스트랩되었습니다. C ++ 기능이 cfront에 추가 되 자마자 cfront는 그 시점부터 해당 기능을 사용할 수 있습니다 (그러나 그 기능을 구현하지는 않음). 이것은 cfront가 C ++ 코드를 C 코드로 변환하는 기능을 가지고 있었기 때문에 효과가있었습니다. 따라서 새로운 플랫폼이 나오면 다른 플랫폼에서 cfront를 사용하여 cfront를 C ++에서 C로 변환 한 다음 새 플랫폼의 C 컴파일러를 사용하여 C에서 객체 코드로 컴파일을 완료 할 수 있습니다.


9

BS가 그 질문에 대답한다고 생각합니다.

첫 번째 C ++ 컴파일러 (Cfront)는 C ++로 작성되었습니다. 이를 구축하기 위해 먼저 C를 사용하여 "C를 사용하여 클래스"-C 전처리기를 작성했습니다. "C with Classes"는 C ++의 직접적인 조상이 된 C 방언이었습니다. 이 전처리 기는 "C with Classes"구문 (예 : 클래스 및 생성자)을 C로 변환했습니다. 모든 언어를 이해하지 못하고 C 컴파일러가 수행 할 수있는 유형 검사를 대부분 남겨두고 개별을 번역 한 전통적인 전 처리기였습니다. 완전한 지식이없는 구조.

그런 다음 "C with Classes"에 Cfront의 첫 번째 버전을 작성했습니다. Cfront는 C ++ 소스의 구문과 의미를 완벽하게 검사하는 전통적인 컴파일러였습니다. 이를 위해 완전한 파서가 작성되었으며, 기호 테이블이 작성되었으며, 각 클래스, 함수 등의 완전한 내부 트리 표현이 작성되었습니다. 또한 C를 출력하기 전에 C ++ 구문의 내부 트리 표현에 대한 소스 레벨 최적화를 수행했습니다. 생성 된 C는 모든 유형 검사에 C를 사용하지 않았습니다. 단순히 C를 어셈블러로 사용했습니다. 결과 코드는 매우 빠릅니다.

먼저 그는 간단한 전처리기에 의해 C로 구현 된 "C with Classes"라는 것을 만들었습니다. 기본적으로 C ++이지만 전처리 기는 거의 확인하지 않았습니다. 그런 다음이를 사용하여 C ++ 번역기의보다 강력한 버전 인 Cfront를 작성하여 형식 검사, 기호 테이블 등을 완성했습니다.


1
기본적으로 C ++ 프로그램을 컴파일 할 때 C로 변환 된 다음 C로 변환 된 후에 다시 기계 코드로 컴파일됩니까?
Pacerier

@Pacerier : 원래 예,하지만 지금은 아닙니다.
Mike Dunlavey

나는 당신의 의견을 이해하지 못합니다. 이제 두 번째 단계를 건너 뛰고 C ++ 소스를 가져 와서 기계 코드로 컴파일하는 컴파일러가 있다는 것을 의미합니까?
Pacerier

7
@Pacerier : 글쎄, 그들은 어셈블리 언어 나 기계 코드로 직접 가지 않습니다. 일반적으로 그들은 먼저 기계 독립적 인 중간 표현 (트리플 또는 쿼드)으로 가서 최적화를 위해 분석합니다. 이를 통해 어셈블리 또는 기계 코드를 생성합니다. 컴파일러 디자인 (Aho & Ullman) 에 관한 책을 집어 들었다면 흥미로울 것입니다.
Mike Dunlavey

1
그가 구축 한 C ++도 현재 존재하는 언어의 일부라는 점에 주목해야합니다. 템플릿이나 새 라이브러리가 없으며 C 캐스팅 만 사용했으며 올바르게 기억하면 예외가 없었습니다.
로봇 고트

2

답변이이 측면을 다루지 않았으므로이 답변을 추가하겠습니다.

기술적으로 코드를 컴파일하기 위해 소프트웨어가 필요하지 않습니다. 필요한 컴파일러 사양이있는 한 실제 컴파일을 수동으로 수행 할 수 있습니다. 이것이 첫 번째 C ++ 컴파일러가 컴파일 된 방식이 아닙니다. 나는 그것이 가능하다는 것을 말하고 있습니다.

어셈블리 언어와 비교하십시오. 초기에 사용되었을 때는 어셈블리 코드를 기계 코드로 변환하는 어셈블러 소프트웨어가 없었습니다. 수작업으로 작성되었지만 어셈블리 언어는 프로그래머에게 더 나은 개요를 제공했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.