Jakie jest pochodzenie Preprocesora C?

30

Preprocesor C jest dołączony do C, ale ma zupełnie inną składnię niż język główny:

  • znaczące spoczynkowo białe znaki (koniec linii kończy instrukcję, przerwa po tym, jak makro określa początek listy zastępczej)

  • bloki oparte na słowach kluczowych zamiast wzmocnionych bloków elifzamiastelse if

  • definicje oparte na słowach kluczowych zamiast deklaracji odzwierciedla użycie, nie =dla definicji wartości

  • wskazówki dotyczące alternatywnej składni łańcucha ( #include <>vs #include "")

  • leniwa ocena (oczywiście C; ale 6.10.3.1 można odczytać jako sugerującą określoną kolejność ekspansji makr, w kilku miejscach, które mają znaczenie)

To naprawdę nie wygląda jak C! Technicznie jest to jego własny język, ale zawsze był używany jako prawie integralna część C i wydaje się bardzo dziwne, że nie zintegrowałby się z nim syntaktycznie.

Wikipedia nie mówi o swojej historii; repozytorium wzorców Portland podaje je mimochodem , ale nie wykracza poza to, że zostało zaprojektowane przez innych ludzi niż reszta strony C. Dennisa Ritchiego z historią C, prawdopodobnie zna odpowiedź, ale niestety nie dostępne dłużej.

Jako makro silnika, to oczywiście ma bardzo różne semantykę z języka wykonawczym, które mogłyby wyjaśnić pewne różnice, ale nie aspektów projektowania wizualnego (jest również jasne, nowoczesne oczy, czy to było pierwotnie przeznaczone jako zdolny z rodzaju z radości , że jego system wymiany pozwala, czy też był to „po prostu” celowy sposób wstawiania funkcji w czasie przed potężnymi optymalizatorami). Wydaje się, że coś bliższego temu, co ostatecznie stało się szablonami C ++, byłoby bardziej logiczną ewolucją w kierunku makr, gdyby semantyka podobna do C była faktycznie punktem wyjścia, ale jest mniej konkretnych dowodów na to niż na składnię.

Czy mamy jakąkolwiek wzmiankę o tym, dlaczego została zaprojektowana w ten sposób lub jakie były wpływy twórców?

Leushenko
źródło
5
archive.org/details/dmr-grab
Mike wspiera Monikę
@ Mike omg dziękuję Naprawdę myślałem, że zawartość witryny została utracona na zawsze, ponieważ nie ma dostępnego do przeglądania wpisu w archiwum.
Leushenko
@MikeSupportsMonica Właśnie miałem zapytać, czy ktoś ma link. Dzięki.
klutt

Odpowiedzi:

17

Od http://www.jslint.com/chistory.html („Rozwój języka C” Dennisa M. Ritchiego):

Wiele innych zmian zaszło w latach 1972-3, ale najważniejsze było wprowadzenie preprocesora, częściowo za namową Alana Snydera [Snyder 74], ale także w uznaniu użyteczności mechanizmów włączania plików dostępnych w BCPL i PL / I. Jego oryginalna wersja była niezwykle prosta i zawierała tylko pliki i proste zamiany ciągów: #include i #define bez parametrów makr. Wkrótce potem został rozszerzony, głównie przez Mike'a Leska, a następnie przez Johna Reisera, aby włączyć makra z argumentami i kompilacją warunkową. Preprocesor był początkowo uważany za opcjonalny dodatek do samego języka. Rzeczywiście przez kilka lat nie było nawet przywoływane, chyba że program źródłowy zawierał na początku specjalny sygnał. Takie podejście utrzymywało się i wyjaśnia zarówno niepełną integrację składni preprocesora z resztą języka, jak i niedokładność jego opisu we wczesnych podręcznikach referencyjnych.

Z relacji w sekcji 4 odnośnika [Snyder 74] połączonego w powyższym cytacie wynika, że ​​Alan Snyder pracował na przenośnym (dziś można powiedzieć „retargetowalnym”) kompilatorze C. Być może była to motywacja, by poprosić o preprocesora.

Nie udało mi się jednak znaleźć żadnych dodatkowych szczegółów na temat samej konstrukcji preprocesora C jako języka.

James Youngman
źródło
1
Zauważ, że Snyder przybył do Bell Labs z MIT, gdzie asembler MIDAS ma instrukcje DEFINE, IFDEF i IFNDEF. Zbieg okoliczności?
Lars Brinkhoff
0

Mogę tylko dodać, że w językach asemblera bardzo często występowały preprocesory asemblera makr, które wyglądają bardzo podobnie do CPP.

Tuntable
źródło