global oder nicht global

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@Darii: Rust ist interessant, könnte aber zu kompliziert und zu ”exotisch” sein, zumindest um ”alte” Programmierer zu gewinnen.

C macht das überprüfen nicht für Dich weil die Sprache nichts von den Grössen weiss. Und Sprachen wie Pascal, die wissen wie gross Arrays sind, haben sich nicht durchgesetzt, unter anderem wegen dieser ”Einschränkung”.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Darii hat geschrieben:Wenn man in C *IMMER* die Größe von Speichersegmenten checken muss warum macht die Sprache das nicht für mich? Das würde eine komplette Klasse von Fehlern ausschließen. Die Lehre aus Heartbleed sollte eben sein, dass man solch gravierende Sprachdefizite nicht durch QA oder (reklamierte) Fertigkeiten des Programmierers kompensieren kann.
Irgendwo muss man beim Entwickeln der Sprache immer einen Schnitt machen. Der nächste wäre dann: Wenn C die Größe von Arrays kennt, warum wird der Speicher nicht automatisch mittels Reference-Counting verwaltet? Dann kommen die nächsten und fragen: Wenn man schon Reference-Counting hat, warum dann nicht gleich einen Garbage-Collector? Das kann beliebig weitergesponnen werden.

Jede Sprache hat ihren Einsatzzweck und wurde dafür entworfen. Bei C wurde eben genau hier ein Schnitt gemacht. Welcher, mit Bezug auf die Sprache, auch sinnvoll ist. C ist so nah an der Maschine, dass eine Prüfung keinen Sinn macht. Zum einen möchte man häufig nicht, dass der Compiler einfach (häufig unnötige) Checks einbaut, zum anderen sind Prüfungen, wie BlackJack schon geschrieben hat, teilweise gar nicht möglich. Arrays sind in C einfache Speicherblöcke, bzw. einfach nur Pointer auf eine Adresse. Was dahinter steht ist vollkommen unbestimmt.

Daraus ergeben sich natürlich viele Vorteile, besonders in der Echzeitfähigkeit und ich der Performance und mit irgendwie muss man sich diese erkaufen. Nicht ohne Grund ist der Python-Interpreter so viel langsamer als reiner C-Code. Wenn ein Programm effizient laufen muss, dann ist die Anzahl der Alternativen mit einem verlässlichen Compiler recht überschaubar.
Das Leben ist wie ein Tennisball.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Darii hat geschrieben:Die Lehre aus Heartbleed sollte eben sein, dass man solch gravierende Sprachdefizite nicht durch QA oder (reklamierte) Fertigkeiten des Programmierers kompensieren kann.
Wenn ich mit einem funktionstüchtigen Fahrrad hinfalle - dann ist das Fahrrad schuld? Oder fehlende Helm? Das sind doch alles nur Werkzeuge, welches jedes für sich einen gewissen Sachverstand in der Benutzung voraussetzt.
Die "Rohheit" von C hat eben ihre Vorteile und kommt zu einem Preis. Preis ist eben all das, was EyDu aufzählt, von Haus aus nicht mitgeliefert wird. Dir ist freigestellt, sowas zu nutzen (nichts hält Dich davon ab, einen smart_ptr zu implementieren), es liegt in Deiner Verantwortung.
Die Hauptvorteile folgen ganz klar aus der Maschinennähe, welche Laufzeiten, Speicherverbrauch und Kompilate klein hält. So schleppen die Wirthsprachen eine kleine Laufzeitumgebung mit, welche die Sicherheitsfeatures vorhält. Das verdoppelt bis verdreifacht mal eben die Laufzeit.

Das C nach wie vor diese ubiquitäre Verbreitung hat, liegt mMn nicht nur an geerbter Verbreitung oder dem "Druck" der alten Programmierer. Die meisten kompilierenden Sprachen verstehen die C-Aufrufkonvention, trotzdem findet man kaum Pascal oder Ada Drittbibliotheken, C++ ist hier die einzige Ausnahme. So werden selbst neue Programmierfelder wie die GPU-Programmierung per C-Syntax erschlossen (siehe OpenCL oder CUDA). Herr Ritchie hat mit der zugegeben schmalbrüstigen C-Lib einen Quasistandard geschaffen, den selbst der letzte Mikrocontrollerhersteller bedienen kann. Die Portierung vieler anderer Sprachen dürfte hier schon an den Systemanforderungen scheitern.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Das ist mir alles klar und das will ich auch nicht abstreiten, aber das Hauptproblem von C ist, dass es keine Möglichkeit gibt auf einen "sicheren" Modus umzuschalten wenn man mal nicht die letzten 2% Geschwindigkeit braucht. In 99% der Fälle in denen C verwendet wird, würde ein Speichercheck zur Laufzeit nicht weh tun, aber sehr viel zur Sicherheit beitragen. C ist optimiert auf einen Grenzfall, den man fast nie braucht.

Das ist der Unterschied zu Rust. Rust ist standardmäßig sicher, mit all den Nachteilen den das mit sich bringt. Aber man darf, wenn man muss, "unsichere" Operationen in unsafe{}-Blöcken durchführen, also Arrays wie in C als Zeiger interpretieren, allgemein mit nullbaren C-artigen Zeigern hantieren, oder komische typecasts machen etc.. Das vereinfacht die Sicherheitsprüfung ungemein. Ein "grep unsafe" über den Code reicht, um die Stellen zu finden, die man sehr genau angucken muss.

Rust benötigt im Gegensatz zu allen anderen Sprachen die C ersetzen wollen weder einen GC noch eine Laufzeitumgebung. Ersterer ist ähnlich die in C++ als smart_pointer in der Library implementiert und letztere kann man beim kompilieren ausstellen. Rust läuft wie schon erwähnt ohne Probleme auf Mikrocontrollern (bis jetzt nur auf ARM).

Kleine Anmerkung: C ist selbst für embedded-Programmierung eigentlich nicht gut genug ist. Man muss sich oft mit häßlichen Makros helfen (C++ ist besser, aber templates werden sehr schnell sehr unleserlich wenn man vergleichsweise einfach Dinge tun will, sofern C++ überhaupt unterstützt wird, siehe PIC) die nicht Teil der Sprache, sondern stumpfes Suchen und Ersetzen durch den Preprocessor sind.
Antworten