표준 라이브러리가 언어 프리미티브를 프로그래밍하지 않는 이유는 무엇입니까? [닫은]


30

나는 언어 자체의 기본 요소 인 비슷한 "함수"를 갖는 대신 stdlib와 같은 표준 라이브러리 (C ++, Java, Python과 같은 모든 프로그래밍 언어)가 왜 존재하는지 생각하고있었습니다.


4
"컴파일러가 단순히 함수 호출을 명령어 세트로 변환 할 수없는 이유"는 무엇을 의미합니까? 대략 컴파일러가 표준 라이브러리를 사용하든 그렇지 않든간에 (오케이, 파이썬은 부분적으로 Java에서 JVM 바이트 코드로, 비슷한 개념입니다). 표준 라이브러리는 실제로 코드-> 명령어 컴파일과 관련이 없습니다.
Delioth

25
@Delioth 나는 Simone이 표준 언어 라이브러리 $ LANG의 모든 것이 왜 그 언어의 기본 구성 / 기능이 아닌지 묻고 있다고 생각합니다. 프로그래밍 언어를 처음 접하는 사람이라면 누구나 합리적인 질문이라고 생각합니다. :
Andres F.

33
표준 라이브러리는 일반적으로 작동하는 프로그래밍 언어와 사람들이 사용할 유용한 언어 사이의 간격을 채 웁니다 .
Telastyn

6
파이썬 표준 라이브러리의 상당 부분은 실제로 C로 작성되었으며 이미 컴파일되었습니다.
ElmoVanKielmo

1
대조적으로, BASIC의 대부분의 구현에서 모든 것은 언어의 일부이며 라이브러리를 전혀 지원하거나 지원하지 않습니다 (여러 구현에서 기계 언어 루틴을 호출하는 기능을 위해 저장).
Euro Micelli

답변:


32

@ Vincent 's (+1) good answer에서 다소 확장 할 수 있습니다 .

컴파일러가 단순히 함수 호출을 일련의 명령어로 변환 할 수없는 이유는 무엇입니까?

적어도 두 가지 메커니즘을 통해 가능합니다.

  • 함수 호출 인라인 — 변환하는 동안 컴파일러는 소스 코드 호출을 함수에 대한 실제 호출 대신 직접 인라인으로 구현할 수 있습니다. 여전히 함수에는 어딘가에 정의 된 구현이 있어야하며 이는 표준 라이브러리에있을 수 있습니다.

  • 내장 함수 — 내장 함수는 라이브러리에서 함수를 찾을 필요없이 컴파일러에 알린 함수입니다. 이들은 일반적으로 다른 방법으로는 실제로 액세스 할 수없는 하드웨어 기능을 위해 예약되어 있으므로 어셈블리 언어 라이브러리 함수 호출에 대한 오버 헤드도 높은 것으로 간주됩니다. (컴파일러는 일반적으로 자동으로 언어로 소스 코드를 인라인 할 수 있지만 내장 메커니즘이있는 어셈블리 함수는 할 수 없습니다.)

그럼에도 불구하고 가장 좋은 방법은 컴파일러가 소스 언어의 함수 호출을 기계어 코드의 함수 호출로 변환하는 것입니다. 재귀, 가상 방법 및 깎아 지른 크기는 인라인이 항상 가능한 것은 아니며 실용적이지 않은 이유입니다. 별도의 컴파일 (객체 모듈), 별도의로드 단위 (예 : DLL)와 같은 또 다른 이유는 빌드의 의도입니다.

대부분의 표준 라이브러리 함수를 intrisics로 만들면 실제로 이점이 없습니다 (실제 이점을 위해 컴파일러에 더 많은 지식을 하드 코딩 할 것입니다). 따라서 기계 코드 호출이 가장 적합합니다.

C는 표준 라이브러리 함수에 유리한 다른 명시 적 언어 설명을 생략 한 주목할만한 언어입니다. 라이브러리는 이미 존재하지만이 언어는 표준 라이브러리 함수에서 더 많은 작업을 수행하고 언어 문법의 명시 적 표현으로 줄였습니다. 예를 들어, 다른 언어로 된 IO에는 다양한 문장의 형태로 자체 구문이 자주 제공되는 반면, C 문법은 IO 문장을 정의하지 않고 단순히 표준 라이브러리를 연기하여 함수 호출을 통해 액세스 할 수있는 모든 것을 제공합니다. 컴파일러는 이미 수행 방법을 알고 있습니다.


3
좋은 대답입니다. C에서 이러한 결정이 내려진 이유에 대한 몇 가지 단어를 추가해야합니다 . 올바르게 기억한다면 주된 이유는 실제로 여러 하드웨어 아키텍처에 대해 C 컴파일러를보다 쉽게 ​​만들 수 있기 때문입니다.
Doc Brown

10
@DocBrown 1975 년까지 프로그래밍 언어 개발 (ALGOL-68, 누구?) 영역에 충분한 예제가 있었는데, 이는 모든 언어를 언어로 직접 구우려고 시도하면 언어 사양을 찾아서 언어 구현을 생성합니다.
Joker_vD

5
비슷한 예가 파이썬에서했던 것입니다 print. 2.x에서는 고유 한 문법을 ​​가진 명령문 이지만 3.x에서는 또 다른 함수 호출이되었습니다. 공식 설명 은 PEP 3105 를 참조하십시오 .
dan04

1
@DocBrown, 이식성은 거의 이유가 아니 었습니다. 유닉스와 C가 만들어 졌을 때, Ken Thompson은 실패한 Multics 프로젝트에서 어떤 개념을 구할 수 있을지 궁금해했던 것처럼 정확히 PDP-7 한 대의 시스템을 위해 설계되고 제작되었습니다. C는 또한 Unix를 (다시) 구현할 수있는 고급 언어를 사용하기 위해 만들어졌습니다. 우리는 기본적으로 상용 다중 플랫폼 OS 및 언어에 대한 심각한 시도가 아니라 소프트웨어 설계 실험입니다. 예를 들어 bell-labs.com/usr/dmr/www/chist.html 을 참조하십시오 .
유로 Micelli

@ EuroMicelli : 나는 모순이 보이지 않습니다. 그리고 당신의 참고 문헌은 언제 이식성이 중요해 졌는지에 대한 많은 세부 사항을 포함하고 있으며, 실제로 C와 Unix 개발 초기에있었습니다. 여기서 추측 할 수는 있지만 C 발명가가 의도적으로 언어를 작게 유지하지 않았다면 언어를 다른 아키텍처에 너무 빠르고 성공적으로 이식 할 가능성은 거의 없었을 것입니다.
Doc Brown

70

이것은 언어 자체를 가능한 한 단순하게 유지하기위한 것입니다. 루프 유형 또는 매개 변수를 함수 등에 전달하는 방법과 같은 언어의 기능과 대부분의 응용 프로그램에 필요한 공통 기능을 구별해야합니다.

라이브러리는 많은 프로그래머에게 유용 할 수있는 함수이므로 공유 할 수있는 재사용 가능한 코드로 만들어집니다. 표준 라이브러리는 프로그래머가 일반적으로 필요로하는 매우 일반적인 기능으로 설계되었습니다. 이런 식으로 프로그래밍 언어는 더 넓은 범위의 프로그래머에게 즉시 유용합니다. 언어 자체의 핵심 기능을 변경하지 않고도 라이브러리를 업데이트하고 확장 할 수 있습니다.


3
항상 그런 것은 아닙니다. PHP예를 들어 방대한 언어 기능과 언어 자체 간에는 거의 차이가 없습니다.
Vahid Amiri

15
간단한 언어의 예로 PHP를 사용하지 않겠습니다
DrBreakalot

3
@DrBreakalot PHP는 매우 간단한 언어입니다. 그것은 일관된 디자인을 가지고 있다고 말하는 것이 아니라 또 다른 문제입니다.
모니카와 함께 가벼운 레이스

19
@LightnessRacesinOrbit PHP를 전혀 "간단한"이라고 부르지 않을 것입니다. 클래스 기반 객체 시스템, 별도의 '기본 값', 독립형 함수, 객체 시스템에 구축 된 일류 클로저, 네임 스페이스 메커니즘, 다양한 "정적"이라는 개념, 문장뿐만 표현으로서 include, require그리고 require_once, 만약 / 대 / 동안 (구조화 프로그래밍), 예외 약한 입력 규칙 복잡 '에러 값'별도의 시스템을 복잡 연산자 우선 순위 규칙, 계속해서 . 이것을 스몰 토크, 구성표, 프롤로그, 포스 등의 단순성과 비교해보십시오.;)
Warbo

3
이 답변에서 암시되었지만 명시 적으로 언급되지 않은 주된 이유는 언어를 가능한 한 단순하게 유지하면 다른 플랫폼에서 구현하기가 훨씬 쉽기 때문입니다. 때문에 표준 라이브러리는 일반적으로 언어 자체에 기록 된 , 그들은 사소하게 이식 할 수 있습니다.
BlueRaja-대니 Pflughoeft

34

다른 답변에서 이미 말한 것 외에도 표준 기능을 라이브러리에 넣는 것은 우려를 분리하는 것입니다 .

  • 언어를 구문 분석하고 코드를 생성하는 것은 컴파일러의 일입니다. 해당 언어로 작성되어 라이브러리로 제공 될 수있는 모든 것을 포함하는 것은 컴파일러의 일이 아닙니다.

  • 사실상 모든 프로그램에 필요한 핵심 기능 을 제공하는 것은 표준 라이브러리 (항상 암시 적으로 사용 가능한 라이브러리) 작업 입니다. 유용한 모든 기능을 포함하는 것은 표준 라이브러리의 작업이 아닙니다.

  • 많은 프로그램이 없이도 수행 할 수있는 보조 기능을 제공하는 것은 표준 라이브러리 (선택 사항)의 역할이지만 여전히 많은 응용 프로그램에서 표준 환경으로의 배송을 보증하는 데 필수적입니다. 지금까지 작성된 모든 재사용 가능한 코드를 포함하는 것은 선택적 라이브러리의 일이 아닙니다.

  • 유용한 재사용 가능한 함수 모음을 제공하는 것은 사용자 라이브러리의 작업입니다. 작성된 모든 코드를 포함하는 것은 사용자 라이브러리의 작업이 아닙니다.

  • 실제로 하나의 응용 프로그램에만 관련된 나머지 코드 비트를 제공하는 것은 응용 프로그램의 소스 코드 작업입니다.

하나의 크기에 맞는 소프트웨어를 원한다면 정말 복잡한 것을 얻을 수 있습니다. 복잡성을 관리 가능한 수준으로 낮추려면 모듈화해야합니다. 그리고 부분적으로 구현할 수 있도록 모듈화해야합니다 .

  • 스레딩 라이브러리는 단일 코어 임베디드 컨트롤러에서 가치가 없습니다. 이 임베디드 컨트롤러의 언어 구현이 pthread라이브러리를 포함하지 않도록 허용하는 것은 올바른 일입니다.

  • 수학 라이브러리는 FPU가없는 마이크로 컨트롤러에서도 가치가 없습니다. 다시 말하지만, sin()마이크로 컨트롤러의 언어 구현자가 인생을 훨씬 더 쉽게 만드는 것과 같은 기능을 제공하지 않아도 됩니다.

  • 핵심 표준 라이브러리조차도 커널을 프로그래밍 할 때 쓸모가 없습니다. write()커널에 대한 syscall 없이는 구현할 수 없으며 , printf()없이는 구현할 수 없습니다 write(). 커널 프로그래머는 write()syscall 을 제공하는 것이 당신의 임무 입니다.

표준 라이브러리에서 이러한 생략을 허용하지 않는 언어는 많은 작업에 적합하지 않습니다 . 일반적이지 않은 환경에서 언어를 유연하게 사용할 수 있으려면 표준 라이브러리가 포함 된 언어에 유연해야합니다. 언어가 표준 라이브러리에 의존할수록 실행 환경에 대해 더 많은 가정을하므로 이러한 전제 조건을 제공하는 환경으로의 사용을 제한합니다.

물론 파이썬이나 자바와 같은 고급 언어 는 환경에 대해 많은 가정을 할 수 있습니다. 그리고 그들은 표준 라이브러리에 많은 것들을 포함시키는 경향이 있습니다. C와 같은 저수준 언어는 표준 라이브러리에서 훨씬 더 적게 제공하며 핵심 표준 라이브러리를 훨씬 작게 유지합니다. 그렇기 때문에 거의 모든 아키텍처에서 작동하는 C 컴파일러를 찾을 수 있지만 파이썬 스크립트를 실행할 수 없습니다.


16

컴파일러와 표준 라이브러리가 분리 된 큰 이유 중 하나는 두 가지 다른 목적으로 사용되기 때문입니다 (둘 다 동일한 언어 사양으로 정의 된 경우에도 해당). 컴파일러는 더 높은 수준의 코드를 기계 명령어로 변환하고 표준 라이브러리는 사전 테스트를 제공합니다 일반적으로 필요한 기능의 구현. 컴파일러 작성자는 다른 소프트웨어 개발자와 마찬가지로 모듈성을 중요하게 생각합니다. 실제로 초기 C 컴파일러 중 일부는 컴파일러를 사전 처리, 컴파일 및 링크를 위해 별도의 프로그램으로 분할했습니다.

이 모듈성은 다음과 같은 많은 장점을 제공합니다.

  • 대부분의 표준 라이브러리 코드는 하드웨어에 구애받지 않고 재사용 할 수 있으므로 새 하드웨어 플랫폼을 지원할 때 필요한 작업량을 최소화합니다.
  • 표준 라이브러리 구현은 속도, 공간, 리소스 사용 등 다양한 방법으로 최적화 할 수 있습니다. 많은 초기 컴퓨팅 시스템에는 하나의 컴파일러 만 사용할 수 있었으며 별도의 표준 라이브러리가있어 개발자가 필요에 따라 구현을 교체 할 수있었습니다.
  • 표준 라이브러리 기능이 없어도됩니다. 예를 들어 베어 메탈 C 코드를 작성할 때 완전한 기능을 갖춘 컴파일러가 있지만 대부분의 표준 라이브러리 기능이 없으며 파일 I / O와 같은 것도 불가능합니다. 컴파일러가이 기능을 구현해야한다면 가장 필요한 일부 플랫폼에서 표준을 준수하는 C 컴파일러를 가질 수 없었습니다.
  • 초기 시스템에서 컴파일러는 하드웨어를 설계 한 회사에서 자주 개발했습니다. 표준 라이브러리는 종종 해당 소프트웨어 플랫폼에 특정한 기능 (시스템 호출과 같은)에 액세스해야했기 때문에 OS 공급 업체가 제공했습니다. 컴파일러 작성자가 하드웨어와 소프트웨어의 서로 다른 모든 조합을 지원해야하는 것은 비현실적이었습니다 (하드웨어 아키텍처와 소프트웨어 플랫폼 모두에서 훨씬 더 다양했습니다).
  • 고급 언어에서는 표준 라이브러리를 동적으로로드 된 라이브러리로 구현할 수 있습니다. 그런 다음 하나의 표준 라이브러리 구현을 여러 컴파일러 및 / 또는 프로그래밍 언어에서 사용할 수 있습니다.

역사적으로 (적어도 C의 관점에서 볼 때), 원래의 사전 표준화 버전의 언어에는 표준 라이브러리가 전혀 없었습니다. OS 공급 업체와 타사는 종종 일반적으로 사용되는 기능으로 가득 찬 라이브러리를 제공하지만 구현마다 다른 것들이 포함되어 있으며 서로 호환되지 않습니다. C가 표준화되었을 때, 그들은 이질적인 구현을 조화시키고 이식성을 향상시키기 위해 "표준 라이브러리"를 정의했습니다. C 표준 라이브러리는 Boost 라이브러리가 C ++ 용으로 개발 한 것처럼 언어와 별도로 개발되었지만 나중에 언어 사양에 통합되었습니다.


6

추가 코너 사례 답변 : 지적 재산권 관리

주목할만한 예는 Microsoft가 Microsoft에서 구입 한 .NET Framework에서 Math.Pow (double, double)를 구현 한 것으로 프레임 워크가 오픈 소스가 된 경우에도 공개되지 않은 상태입니다. (정확히 말하면, 위의 경우 라이브러리보다는 내부 호출이지만 아이디어는 유지됩니다.) 언어 자체와 분리 된 라이브러리 (이론적으로 표준 라이브러리의 하위 세트)는 언어 후원자에게 투명성 유지 대상과 공개되지 않은 대상 (제 3 자와의 계약 또는 기타 IP 관련 사유로 인해) 사이의 경계.


혼란 스럽습니다. 링크하는 페이지 Math.Pow에는 구매 또는 인텔에 대한 언급이 없으며 기능 구현의 소스 코드를 읽는 사람들에 대해 이야기합니다.
Monica와 Lightness Races

@LightnessRacesinOrbit – hm, 여전히 "intel"을 검색 할 때 볼 수 있습니다. 또한 최근 소스 코드 (가장 최근 주석)에 대한 참조와 공개적으로 사용 가능하지만 복잡하고 주석 처리 된 비 효율성에 대한 대체 구현 (두 번째 답변에서)에 대한 참조를 찾을 수있어 원래 구현이 여전히 공개되지 않은 이유를 알 수 있습니다. 진정으로 효율적인 구현을 위해서는 퍼블릭 도메인에서 반드시 사용할 수없는 CPU 수준에 대한 많은 세부 사항에 대한 심층적 인 지식이 필요할 수 있습니다.
miroxlav

5

버그와 디버깅.

버그 : 모든 소프트웨어에 버그가 있고 표준 라이브러리에 버그가 있고 컴파일러에 버그가 있습니다. 언어 사용자는 컴파일러와 달리 표준 라이브러리에있을 때 이러한 버그를 찾고 해결하는 것이 훨씬 쉽습니다.

디버깅 : 표준 라이브러리의 스택 추적을보고 오류가 발생할 수있는 내용을 이해하는 것이 훨씬 쉽습니다. 그 스택 추적에는 코드가 이해하기 때문에. 물론 더 깊이 파고 내면의 기능을 추적 할 수도 있지만, 하루 종일 사용하는 언어라면 훨씬 더 쉽습니다.


5

이것은 훌륭한 질문입니다!

최첨단

예를 들어 C ++ 표준은 컴파일러 나 표준 라이브러리에서 구현해야하는 것을 지정하지 않습니다. 단지 구현을 참조합니다 . 예를 들어, 예약 된 심볼은 컴파일러 (내장형)와 표준 라이브러리에 의해 서로 바꿔서 정의됩니다.

그러나 내가 아는 모든 C ++ 구현에는 컴파일러에서 제공하는 최소한의 내장 함수와 표준 라이브러리에서 제공하는 최대한의 내장 함수가 있습니다.

따라서 기술적으로 표준 라이브러리를 컴파일러에서 고유 기능으로 정의하는 것이 가능하지만 실제로는 거의 사용되지 않는 것 같습니다.

왜?

기능의 일부를 표준 라이브러리에서 컴파일러로 옮길 생각을 생각해 보자.

장점 :

  • 더 나은 진단 : 내장 함수는 특수한 경우가 있습니다.
  • 더 나은 성능 : 내장 함수는 특수한 경우가 있습니다.

단점 :

  • 컴파일러 질량 증가 : 각 특수 사례는 컴파일러에 복잡성을 추가합니다. 복잡성은 유지 보수 비용과 버그 가능성을 증가시킵니다.
  • 느린 반복 : 기능의 구현을 변경하려면 컴파일러 자체를 변경해야하므로 std실험을 위해 작은 라이브러리 (외부 ) 만 만드는 것이 더 어렵습니다 .
  • 진입률이 높을수록 : 변경하는 것이 더 비싸고 더 어려울수록 사람들이 더 적게 들어올 수 있습니다.

즉, 컴파일러로 무언가를 옮기는 것은 현재와 ​​미래에 비싸기 때문에 확실한 경우가 필요합니다. 일부 기능의 경우 필수 (일반 코드로 작성할 수 없음)가 필요하지만 컴파일러로 이동하고 표준 라이브러리에서이를 작성 하기 위해 최소한의 일반 조각을 추출 해야합니다.


5

언어 디자이너로서 저는 여기에 다른 답변들 중 일부를 에코하고 싶지만 언어를 구축하는 사람의 눈을 통해 제공하고 싶습니다.

가능한 모든 것을 추가하면 API가 완료되지 않습니다. API는 가능한 모든 것을 꺼내고 나면 완료됩니다.

프로그래밍 언어는 일부 언어를 사용하여 지정해야합니다. 귀하의 언어로 작성된 모든 프로그램의 의미를 전달할 수 있어야합니다. 이 언어는 매우 쓰기 하드, 심지어 더 열심히 잘 작성. 일반적으로 컴퓨터가 아니라 다른 개발자, 특히 언어에 대한 컴파일러 또는 해석기를 작성하는 개발자에게 의미를 전달하는 데 사용되는 매우 정확하고 체계적인 영어 형태 인 경향이 있습니다. 다음은 C ++ 11 사양 [intro.multithread / 14]의 예입니다.

M의 값 계산 B와 관련하여 원자 객체 M에 대한 부작용의 가시적 인 순서는 M의 수정 순서에서 부작용의 최대 연속 서브 시퀀스이며, 여기서 제 1 부작용은 B에 대하여 보인다 모든 부작용에 대해 B가 그 전에 발생하는 것은 아닙니다. 평가 B에 의해 결정된 원자 물체 M의 값은 B와 관련하여 M의 가시적 인 순서로 어떤 동작에 의해 저장된 값이어야한다. [참고 : 값의 부작용의 가시적 인 순서는 보여 질 수있다 아래의 일관성 요구 사항에 따라 계산이 고유합니다. — 끝 노트]

블렉! C ++ 11이 멀티 스레딩을 처리하는 방법을 이해하는 데 뛰어 들었던 사람은 왜 문구가 너무 불투명 해야하는지 이해할 수 있지만 그 사실이 ... 음 ... 너무 불투명하다는 사실을 용서하지는 않습니다!

std::shared_ptr<T>::reset표준의 라이브러리 섹션에서 의 정의와 대조 하십시오.

template <class Y> void reset(Y* p);

효과 : 동등shared_ptr(p).swap(*this)

차이점은 무엇입니까? 언어 정의 부분에서, 작가는 독자가 언어 프리미티브를 이해한다고 가정 할 수 없습니다. 모든 것은 영어 산문으로 신중하게 지정해야합니다. 라이브러리 정의 부분에 도달하면 언어를 사용하여 동작을 지정할 수 있습니다. 이것은 종종 훨씬 쉽다!

원칙적으로, "언어 프리미티브 (language primitives)"와 "표준 라이브러리"기능. 실제로이 줄은 표현하기 위해 설계된 언어를 사용하여 언어의 가장 복잡한 부분 (예 : 알고리즘을 구현해야하는 부분)을 작성할 수 있기 때문에 그리는 데 매우 유용합니다.

그리고 실제로 흐릿한 선이 보입니다.

  • 자바에서 java.lang.ref.Reference<T> 표준 라이브러리 클래스에 의해 서브 클래스 java.lang.ref.WeakReference<T> java.lang.ref.SoftReference<T>java.lang.ref.PhantomReference<T>때문에의 행동에 Reference너무 깊이가 "표준 라이브러리"클래스로 구현하는 과정의 부분에 일부 제한을 넣을 필요가 있다고 Java 언어 사양과 짝을 이루고있다.
  • C #에는 델리게이트의 개념을 캡슐화하는 System.Delegate 클래스가 있습니다. 이름에도 불구하고 대리인이 아닙니다. 또한 파생 클래스를 만들 수없는 추상 클래스 (인스턴스화 할 수 없음)입니다. 언어 사양으로 작성된 기능을 통해 시스템 만이를 수행 할 수 있습니다.

2

이는 기존 답변에 대한 추가로 의미가 있습니다 (댓글이 너무 깁니다).

표준 라이브러리에는 다른 두 가지 이유가 있습니다.

진입 장벽

특정 언어 기능이 라이브러리 함수에 있고 어떻게 작동하는지 알고 싶다면 해당 함수의 소스를 읽을 수 있습니다. 버그 보고서 / 패치 / 풀 요청을 제출하려면 일반적으로 수정 및 테스트 사례를 코딩하는 것이 어렵지 않습니다. 컴파일러에 있다면 내부를 파헤칠 수 있어야합니다. 동일한 언어로되어 있더라도 (자체 존중 컴파일러는 자체 호스팅되어야 함) 컴파일러 코드는 응용 프로그램 코드와 다릅니다. 올바른 파일을 찾는 데에도 시간이 오래 걸릴 수 있습니다.

당신이 그 길을 가면 많은 잠재적 인 기여자들로부터 자신을 차단하고 있습니다.

핫 코드 로딩

많은 언어에서이 기능을 어느 정도 제공하지만 핫 리로드를 수행하는 코드를 핫 리로드하는 것은 매우 복잡합니다. SL이 런타임과 분리 된 경우 다시로드 할 수 있습니다.


3
"자기 존중 컴파일러는 자체 호스팅해야합니다"– 전혀 아닙니다. 이러한 모든 언어를 컴파일하기 위해 C, C ++, Objective-C, Swift, Fortran 등으로 작성된 LLVM 버전을 갖는 것은 의미가 없습니다.
gnasher729

@ gnasher729 (CLR과 같은 다른 다국어 대상과 함께) 특별한 경우가 아닙니까?
Jared Smith

@ JaredSmith 나는 그것이 특별한 것이 아니라 일반적인 경우라고 말할 것입니다. 아무도 더 이상 "컴파일러"를 모 놀리 식 애플리케이션으로 쓰지 않습니다. 대신 컴파일러 시스템을 생성 합니다. 완전한 컴파일러의 기능의 대부분은 컴파일되는 특정 언어와 완전히 독립적 이며, 언어에 따라 다른 코드 를 작성하는 것이 아니라 언어의 문법을 정의하는 다른 데이터 를 제공하여 언어에 따라 많은 부분을 수행 할 수 있습니다. 컴파일하고 싶다.
alephzero

2

이것은 흥미로운 질문이지만 이미 많은 좋은 답변이 있으므로 완전한 답변을 시도하지는 않습니다.

그러나 내가 생각하지 않는 두 가지 사항은 충분히주의를 기울였습니다.

첫 번째는 모든 것이 매우 명확하지 않다는 것입니다. 다르게 행동해야 할 이유가 있기 때문에 약간의 스펙트럼입니다. 예를 들어, 컴파일러는 종종 표준 라이브러리 및 해당 기능에 대해 알고 있습니다. 예제의 예 : C의 "Hello World"함수 인 printf는 내가 생각할 수있는 가장 좋은 것입니다. 그것은 라이브러리 함수이며, 플랫폼에 따라 다르기 때문에 정렬되어야합니다. 그러나 잘못된 호출에 대해 프로그래머에게 경고하려면 컴파일러에서 동작 (구현 정의)을 알아야합니다. 이것은 특히 깔끔하지는 않지만 좋은 타협으로 보였습니다. 덧붙여서, 이것은 대부분의 "이 디자인이 왜 필요한지"질문에 대한 진정한 해답입니다. 항상 "이것이 분명한 방법이었다"또는 "

둘째는 표준 라이브러리가 모든 표준이 될 수 없다는 것입니다. 언어가 바람직한 상황은 많지만 일반적으로 언어와 함께 제공되는 표준 라이브러리는 실용적이지 않고 바람직하지 않습니다. 비표준 플랫폼에서 C와 같은 시스템 프로그래밍 언어의 경우가 가장 일반적입니다. 예를 들어, OS 또는 스케줄러가없는 시스템이있는 경우 스레딩이 없습니다.

표준 라이브러리 모델 (및 스레딩이 지원됨)을 사용하면이를 깨끗하게 처리 할 수 ​​있습니다. 컴파일러는 거의 동일하며 적용되는 라이브러리의 비트를 제거하고 제거 할 수없는 것은 재사용 할 수 있습니다. 이것이 컴파일러에 구워지면 문제가 발생하기 시작합니다.

예를 들면 다음과 같습니다.

  • 호환되는 컴파일러는 될 수 없습니다.

  • 표준과의 편차를 어떻게 표시 하시겠습니까? 일반적으로 파이썬 가져 오기 또는 표준 라이브러리 모델에 누락 된 항목이 있으면 쉽게 문제를 가리키는 C 포함 포함 형식의 가져 오기 / 포함 구문이 있습니다.

'라이브러리'기능을 조정하거나 확장하려는 경우에도 비슷한 문제가 발생합니다. 생각보다 훨씬 일반적입니다. 스레딩을 고수하기 위해 : Windows, Linux 및 일부 이국적인 네트워크 처리 장치는 모두 다르게 스레딩을 수행합니다. 리눅스 / 윈도우 비트는 상당히 정적이고 동일한 API를 사용할 수 있지만 NPU는 요일에 따라 바뀌고 API도 함께 변경됩니다. 이런 종류의 일을 분리 할 방법이 없다면 사람들은 어떤 비트를 지원 / 수행 할 필요가 없는지 신속하게 결정할 수있다.

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