Gegenwärtig wird C als niedrige Sprache betrachtet , aber in den 70er Jahren wurde es als niedrige Sprache angesehen? War der Begriff damals überhaupt gebräuchlich?
Viele beliebte höhere Sprachen gab es erst Mitte der 80er Jahre und darüber hinaus. Ich bin gespannt, ob und wie sich die Natur niedriger Niveaus im Laufe der Jahre verändert hat.
programming-languages
c
history
joeyfb
quelle
quelle
Antworten:
Um die historischen Aspekte der Frage zu beantworten:
Die Designphilosophie wird in der C-Programmiersprache von Brian Kernighan und C-Designer Dennis Ritchie erklärt, dem "K & R", von dem Sie vielleicht schon gehört haben. Das Vorwort zur ersten Ausgabe sagt
und die Einführung sagt
Die Liste wird eine Weile fortgesetzt, bevor der Text fortgesetzt wird:
(Ich habe nur die zweite Ausgabe von 1988, aber der Kommentar unten zeigt, dass der zitierte Text der gleiche ist wie in der ersten Ausgabe von 1978.)
Also, ja, die Begriffe "High Level" und "Low Level" waren damals gebräuchlich, aber C wurde entwickelt, um irgendwo im Spektrum dazwischen zu liegen. Es war möglich, Code in C zu schreiben, der auf Hardwareplattformen portierbar war, und dies war das Hauptkriterium dafür, ob eine Sprache zu dieser Zeit als hoch angesehen wurde. In C fehlten jedoch einige Merkmale, die für Hochsprachen charakteristisch waren, und dies war eine Entwurfsentscheidung zugunsten der Einfachheit.
quelle
Dies hängt von Ihrer Definition der Hochsprache und der Niedrigsprache ab. Bei der Entwicklung von C wurde alles, was über Assembler lag, als Hochsprache betrachtet. Das ist ein niedriger Balken, um zu löschen. Später verlagerte sich diese Terminologie zu einem Punkt, an dem manche heutzutage sogar Java als eine Sprache auf niedriger Ebene betrachten würden.
Selbst innerhalb der Hochsprachenlandschaft der 70er Jahre ist darauf hinzuweisen, dass C ein relativ niedriges Niveau aufweist. Die Sprache C ist im Grunde genommen B plus ein einfaches Typsystem, und B ist nicht viel mehr als eine bequeme prozedurale / strukturierte Syntaxschicht für die Assemblierung. Da das Typsystem über der nicht typisierten Sprache B nachgerüstet wird, können Sie an einigen Stellen Typanmerkungen weglassen und
int
werden angenommen.C verzichtet bewusst auf teure oder schwer zu implementierende Funktionen, die zu diesem Zeitpunkt bereits etabliert waren, wie z
C hat einige interessante Funktionen:
Zu der Zeit, als C entwickelt wurde, waren andere innovative Sprachen wie COBOL, Lisp, ALGOL (in verschiedenen Dialekten), PL / I, SNOBOL, Simula und Pascal bereits veröffentlicht und / oder für bestimmte Problembereiche weit verbreitet. Die meisten dieser vorhandenen Sprachen waren jedoch für die Programmierung von Großrechnern vorgesehen oder waren akademische Forschungsprojekte. ZB als ALGOL-60 zum ersten Mal als universelle Programmiersprache entwickelt wurde, existierte die notwendige Technologie und Informatik, um es zu implementieren, noch nicht. Einige davon (einige ALGOL-Dialekte, PL / I, Pascal) waren auch für die Programmierung auf niedriger Ebene gedacht, hatten jedoch tendenziell komplexere Compiler oder waren zu sicher (z. B. keine uneingeschränkten Zeiger). Pascal fehlt insbesondere eine gute Unterstützung für Arrays variabler Länge.
Im Vergleich zu diesen Sprachen lehnt C "elegante" und teure Funktionen ab, um für die Low-Level-Entwicklung praktischer zu sein. C war nie in erster Linie ein Forschungsprojekt für Sprachdesign. Stattdessen war es ein Ableger der Unix-Kernel-Entwicklung auf dem PDP-11-Minicomputer, der vergleichsweise ressourcenbeschränkt war. Für seine Nische (eine minimalistische Low-Level-Sprache zum Schreiben von Unix mit einem einfach zu portierenden Single-Pass-Compiler) ist C absolut herausragend - und über 45 Jahre später immer noch die Verkehrssprache der Systemprogrammierung.
quelle
%r10
der "statische Kettenzeiger", von dem Sie genau sprechen. Für C ist es nur ein weiteres Rubbellos-Register, aber ich denke, Pascal würde es verwenden. (GNU C-verschachtelte Funktionen verwenden es, um einen Zeiger an den äußeren Gültigkeitsbereich zu übergeben, wenn eine solche Funktion nicht inline ist (z. B. wenn Sie einen Funktionszeiger darauf setzen, damit der Compiler ein Trampolin mit Maschinencode auf dem Stapel erstellt): Akzeptanz von regulär Verwendung von R10 und R11 )a = b;
um eine ganze Struktur so zu kopieren, wie Sie es in ISO C89 können. In frühen C-Versionen waren benutzerdefinierte Typen definitiv zweitklassig und konnten nur als Funktionsargumente als Referenz übergeben werden. Cs Abneigung gegen Arrays und auch Warum unterstützt C ++ die memberweise Zuweisung von Arrays innerhalb von Strukturen, aber nicht generell?In den frühen 1970er Jahren war C mit modernen Konstrukten ein blendender Hauch frischer Luft, so dass das gesamte UNIX-System mit vernachlässigbarem Platz- oder Leistungsverlust aus der Assemblersprache in C umgeschrieben werden konnte. Viele Zeitgenossen bezeichneten es damals als Hochsprache.
Die Autoren von C, in erster Linie Dennis Ritchie, waren vorsichtiger und sagten im Artikel des Bell System Technical Journal: "C ist keine Hochsprache." Mit einem ironischen Lächeln und der Absicht, provokativ zu sein, würde Dennis Ritchie sagen, es sei eine Sprache mit niedrigem Sprachniveau. Zu seinen Konstruktionszielen für C gehörte es vor allem, die Sprache nahe an der Maschine zu halten und dennoch Portabilität zu gewährleisten, dh Maschinenunabhängigkeit.
Weitere Informationen finden Sie im Original-BSTJ-Artikel:
Danke Dennis. Mögest du in Frieden ruhen.
quelle
Wie ich an anderer Stelle auf dieser Site schrieb, als jemand das Muster der Verwaltung von malloc / freiem Speicher als "Low-Level-Programmierung" bezeichnete,
Im Kontext war dies in den frühen 90ern, lange nachdem C herauskam.
quelle
malloc()
indem Sie den resultierenden Speicher direkt aufrufenbrk(2)
odermmap(2)
selbst verwalten. Es ist eine gewaltige PITA, für die es keinen vorstellbaren Nutzen gibt (es sei denn, Sie implementieren zufällig eine malloc-artige Sache), aber Sie können es tun.In vielen Antworten wurde bereits auf frühe Artikel verwiesen, in denen Dinge wie „C ist keine Hochsprache“ gesagt wurden.
Ich kann mich jedoch nicht dagegen wehren, viele, wenn nicht die meisten oder alle HLLs zu der Zeit - Algol, Algol-60, PL / 1, Pascal - haben die Überprüfung der Array-Grenzen und die Erkennung von numerischen Überläufen bereitgestellt.
Das letzte Mal habe ich überprüft, ob Puffer- und Ganzzahlüberläufe die Hauptursache für viele Sicherheitslücken sind. ... Ja, immer noch der Fall ...
Die Situation für die dynamische Speicherverwaltung war komplizierter, dennoch war C-style malloc / free ein großer Sicherheitsrückschritt.
Wenn Ihre Definition von HLL also "viele Bugs auf niedriger Ebene automatisch verhindert" enthält, wäre der traurige Zustand der Cybersicherheit sehr unterschiedlich, wahrscheinlich besser, wenn C und UNIX nicht vorgekommen wären.
quelle
popcnt
.Betrachten Sie ältere und viel höhere Sprachen vor C (1972):
Fortran - 1957 (nicht viel höher als C)
Lisp - 1958
Cobol - 1959
Fortran IV - 1961 (nicht viel höher als C)
PL / 1 - 1964
APL - 1966
Plus eine Mittelstufensprache wie RPG (1959), meistens eine Programmiersprache, um auf Plugboards basierende Einheitsaufzeichnungssysteme zu ersetzen.
Aus dieser Perspektive schien C eine sehr niedrige Sprache zu sein, nur ein wenig über den Makroassemblern, die zu dieser Zeit auf Großrechnern verwendet wurden. Bei IBM-Mainframes wurden Assembler-Makros für den Datenbankzugriff verwendet, z. B. BDAM (Basic Disk Access Method), da die Datenbankschnittstellen (zu diesem Zeitpunkt) nicht nach Cobol portiert worden waren, was zu einer Vermischung von Assembly und führte Cobol-Programme, die noch heute auf IBM-Mainframes verwendet werden.
quelle
Die Antwort auf Ihre Frage hängt davon ab, um welche C-Sprache es sich handelt.
Die Sprache, die in Dennis Ritchies C-Referenzhandbuch von 1974 beschrieben wurde, war eine einfache Sprache, die den Programmierkomfort höherer Programmiersprachen bot. Von dieser Sprache abgeleitete Dialekte waren ebenfalls eher einfache Programmiersprachen.
Als der C-Standard 1989/1990 veröffentlicht wurde, beschrieb er jedoch nicht die für die Programmierung tatsächlicher Maschinen populäre Low-Level-Sprache, sondern eine höhere Sprache, die sein könnte - aber nicht sein musste. -implementiert in untergeordneten Begriffen.
Wie die Autoren des C-Standards bemerken, war eines der Dinge, die die Sprache nützlich machten, dass viele Implementierungen als Assembler auf hoher Ebene behandelt werden konnten. Da C auch als Alternative zu anderen Hochsprachen verwendet wurde und viele Anwendungen nicht die Fähigkeit erforderten, Dinge zu tun, die Hochsprachen nicht konnten, erlaubten die Autoren des Standards, dass sich Implementierungen willkürlich verhalten wenn Programme versuchten, Konstrukte auf niedriger Ebene zu verwenden. Folglich war die von der C-Norm beschriebene Sprache niemals eine Programmiersprache auf niedriger Ebene.
Überlegen Sie, wie Ritchies Sprache und C89 das Codefragment anzeigen, um diese Unterscheidung zu verstehen:
Auf einer Plattform, auf der "char" 8 Bit, "int" 16 Bit Big-Endian, "float" 32 Bit und Strukturen ohne spezielle Auffüll- oder Ausrichtungsanforderungen sind, beträgt die Größe von "struct foo" 8 Byte.
In Ritchies Sprache würde das Verhalten der letzten Anweisung die in "p" gespeicherte Adresse annehmen, 3 * 8 + 2 [dh 26] Bytes hinzufügen und einen 16-Bit-Wert aus den Bytes an dieser und der nächsten Adresse abrufen Fügen Sie diesem Wert einen hinzu, und schreiben Sie diesen 16-Bit-Wert in dieselben zwei Bytes zurück. Das Verhalten würde so definiert, dass es auf das 26. und 27. Byte folgt, das auf das unter der Adresse p angegebene folgt, ohne Rücksicht darauf, welche Art von Objekt dort gespeichert ist.
In der durch den C-Standard definierten Sprache würde für den Fall, dass * p ein Element eines "struct foo []" identifiziert, auf das mindestens drei vollständigere Elemente dieses Typs folgen, die letzte Anweisung dem Mitglied y von eins hinzufügen das dritte Element nach * p. Unter keinen anderen Umständen würde das Verhalten durch den Standard definiert.
Ritchies Sprache war eine einfache Programmiersprache, da sie es einem Programmierer ermöglichte, Abstraktionen wie Arrays und Strukturen zu verwenden, wenn dies zweckmäßig war, und das Verhalten in Bezug auf das zugrunde liegende Layout von Objekten im Speicher definierte. Im Gegensatz dazu definiert die von C89 und späteren Standards beschriebene Sprache die Dinge im Sinne einer übergeordneten Abstraktion und definiert nur das Verhalten von Code, das damit übereinstimmt. Qualitativ hochwertige Implementierungen, die für die Programmierung auf niedriger Ebene geeignet sind, verhalten sich in mehr Fällen als im Standard vorgeschrieben, aber es gibt kein "offizielles" Dokument, in dem angegeben ist, was eine Implementierung tun muss, um für solche Zwecke geeignet zu sein.
Die von Dennis Ritchie erfundene C-Sprache ist daher eine einfache Sprache und wurde als solche anerkannt. Die vom C-Normungsausschuss erfundene Sprache war jedoch nie eine Sprache mit niedrigem Sprachniveau, da keine Garantien für die Implementierung vorlagen, die über die Vorgaben des Standards hinausgingen.
quelle