Golem: C ist eine feindselige Sprache

Status
Für weitere Antworten geschlossen.
Auch C und C++ und Java haben anfangs Hype gebraucht. Man kann es auch Marketing nennen.

C nicht. Über den Erfolg von C hat sich Dennis Ritchie noch 2000 gewundert. Bei gerade mal zweieinhalb unter Unix verfügbaren Programmiersprachen war ein großes Marketinggetrommel für "Hauptsache, es ist nicht Assembler" keinesfalls nötig. Heute, da Go und Rust und D (scnr) und C# und Swift darum wetteifern, das bessere C sein zu dürfen, sieht das schon anders aus.

C hat sich nicht aus Qualitätsgründen durchgesetzt, sondern, weil es mitsamt seiner Mutterplattform einfach lange genug da war. Mainframes sind Edit: nicht mehr die führende Hardwaresparte, unixoide Systeme werden hingegen immer mehr. Tja, nun.

Es zeigt doch schon, dass es gut und gerne 4-5 unterschiedliche String-Copy Funktionen gibt, weil alle davor unsicher waren. Das sagt doch schon eindeutig: Die Sprache ist unsicher.

"Die aktuell für sicher gehaltene strcpy-Version ist die dritte" ist nicht mal ansatzweise identisch mit "die Sprache ist unsicher".

Betrifft nur leider meist C/C++ Programme ;)

Ja, komisch - wenn, sagen wir, 80 Prozent (diese Zahl habe ich mir frei ausgedacht) der Software in C/C++ geschrieben ist, ist rein zahlenmäßig eben auch erstaunlich viel unsichere Software in C/C++ geschrieben. Sichere nur halt auch.

Nicht der Programmierer ist das Problem, sondern die Sprache.

Unsinn. Das würde im Umkehrschluss bedeuten, dass es eine Sprache gibt, in der es unmöglich ist, unsicher zu programmieren. Welche wäre das?
 
Zuletzt bearbeitet von einem Moderator:
Derzeit passiert ja im LLVM SAFECode auch einiges. Das ist eben ein anderer Ansatz, die Probleme, die es so gibt zu "beheben", wenn man das so nennen kann.

Sowas ist halt allgemein auch eher "mit einem Vorschlaghammer um sich schlagen und hoffen, dass man genug Probleme damit trifft". ;)

Jeglichen C-Code allgemein sicher kriegen, ob man nun weiteren Code drum rum kleistert oder versucht mit komplexer Analysesoftware versucht die Probleme zu finden, sind meiner Meinung nach halt nur eine Lösung für bestehende Software die bereits aus mehreren zehntausend bis Millionen Codezeilen besteht.

Mir geht es ja persönlich nicht darum, dass jetzt _alles_ neu geschrieben wird, aber gerade kleinere Programme, Hilfsfunktionen oder sowas in der Art, da kann man durchaus darüber nachdenken. Gerade die im Artikel erwähnten Parser für diverse Dateiformate. Statt dort jetzt die nächsten Jahre daran rumdoktorn, dass das mal sicher ist, kann man das auch einfach mal "von Grund auf" lösen.

Neue Software sollte darin einfach nicht mehr geschrieben werden.

Unsinn. Das würde im Umkehrschluss bedeuten, dass es eine Sprache gibt, in der es unmöglich ist, unsicher zu programmieren. Welche wäre das?

Absolute Sicherheit gibt's natürlich nicht. Gerade algorithmische Unsicherheit kriegst du mit der Sprache alleine nicht beseitigt. Aber ich verstehe weiter das Problem nicht, eine Sprache zu benutzen die einfach mal komplette Problemklassen in Programmcode gar nicht erst erlaubt, weil sie von vornherein eh falsch wäre? Ist ja nicht so als wenn z.B. Rust dich in irgendwas einschränkt. Es ist eine Sprache entworfen für Systemsoftware und nicht wie Java oder C# eine Sprache für Anwendungssoftware.

Und wie ich schon sagte: Wir sehen die Probleme von C jeden Tag. Jedes mal wenn du ein Sicherheitsupdate für deinen Computer einspielst, dann kannst du sicher sein, dass da hauptsächlich irgend eine Form von Buffer Overflow enthalten war. Klar nicht alles, aber noch das Meiste.
 
@CrimsonKing:

Anfangs bei Unix nicht. Aber es ist ja nicht so, dass C jetzt nur auf Unix geblieben ist. Es gab da durch aus einige Sachen, wo es verspätet Hypes gab. Selbst im Microcontrollerbereich gab's da Glaubenskriege in Richtung Assembler, C oder ganz was anderes.

Dass sich C nicht aus Qualitätsgründen durchgesetzt hat bestreitet glaube ich niemanden.

Und klar, ich verwende da den Begriff Hype sehr dehnbar und er ist definitiv nicht mit dem was gerade mit Rust und Go passiert vergleichbar. Das hat aber glaube ich auch vor allem damit zu tun wie sich der.. ich nenne es mal "IT-Sektor" entwickelt hat, also wie der Stellenwert ist, wie viele Leute Programmierer sind, wie sich das auch kulturell geändert hat. Dementsprechend haben sich auch Hype und Marketing massiv geändert.

Ich kann's auch anders formulieren. Auch damals hat es Leute gegeben, die wollten dass sich C durchsetzt, wo das noch nicht der Fall war. Die Leute waren wohl viel mehr Geeks und viel weniger. Es gab noch kein Internet und keine üblichen Orte um Projekte zu hypen und Mailing listen mit "macht alles in X" zuzumüllen gab's auch noch nicht.

Mir ging's da teilweise auch um ganz andere Sachen, wie C vs Pascal und ähnliches, welches zwischendurch mal echt nach einer Konkurrenz aussah und heute praktisch tot ist.

Und ich würde zumindest Go und C# mal außen vor lassen. Die konkurrieren ja relativ wenig mit C und auch wenn Go am Anfang teilweise so vermarktet wurde ist das jetzt nicht die Sprache, wo man typischerweise mit C rangeht. Und zu C#: Auch wenn Java damals Leute von C/C++ umworben hat ist glaube ich der Bereich im Großen und Ganzen auch ziemlich getrennt mittlerweile und ich würde C# eher als Alternative zu Java ansetzen. Damit bleiben von den erwähnten nur D und Rust. Und auch wenn ich D nicht so kenne dürfte da das kleine Unternehmen und der fehlende Hype zumindest ein Grund dafür sein, dass es sich (bisher?) so gar nicht etablieren konnte. Ich meine jetzt nicht als C-Ersatz, sondern einfach, dass es kaum Leute erreicht hat.

Aber gut, ich lasse das mal mit der Diskussion um Hypes oder warum sich C außerhalb von Unix durchgesetzt hat. Darum ging's mir nicht und ich gebe dir recht, dass das nicht wirklich vergleichbar mit dem ist, was jetzt passiert. War ein blöder Vergleich. Stimmt! :)

@-Nuke-: War auch gar nicht irgendwie wertend gemeint, sondern dass es einfach ein anderer Ansatz ist sowas wie C, aber sicher zu haben. Und Rust ist auch einer. Mal komplett neutral gesagt. Ob der Ansatz gut ist, Sinn macht, sich durchsetzen wird oder sonst was will ich mal nicht bewerten. Sondern einfach sagen, dass es da mehrere Ansätze gibt, die zeigen, dass das Problem gesehen wird, ernst genug, dass es immer mal wieder Projekte gibt und da immer mal wieder interessante Ideen abfallen, die es häufig in Compiler oder andere Projekte machen bzw. selbst groß werden..
 
Es ist eine Sprache entworfen für Systemsoftware und nicht wie Java oder C# eine Sprache für Anwendungssoftware.

Weshalb der Rust-Sponsor Mozilla auch erst mal einen Webbrowser darin schreibt. Systemsoftware habe ich anders in Erinnerung.

Wir sehen die Probleme von C jeden Tag. Jedes mal wenn du ein Sicherheitsupdate für deinen Computer einspielst, dann kannst du sicher sein, dass da hauptsächlich irgend eine Form von Buffer Overflow enthalten war.

Wofür die Sprache, deren Compiler im Bestfall genau das tut, was man ihm aufträgt, exakt überhaupt nichts kann.

Das hat aber glaube ich auch vor allem damit zu tun wie sich der.. ich nenne es mal "IT-Sektor" entwickelt hat, also wie der Stellenwert ist, wie viele Leute Programmierer sind, wie sich das auch kulturell geändert hat.

Was ich persönlich für einen großen Fehler halte. Es gibt zu viele Programmierer und zu wenige Programme. Das wird mit dieser unsäglichen Politik des "Programmierens ab Grundschule", von der viel geredet wird, keineswegs besser. Davon wird man kein besserer Mensch. Aber gut, das ist ein heikles Thema.

Mir ging's da teilweise auch um ganz andere Sachen, wie C vs Pascal und ähnliches, welches zwischendurch mal echt nach einer Konkurrenz aussah und heute praktisch tot ist.

Pascal hat ein Kommerzproblem. Außer Borland, das irgendwann aufhörte, bezahlbare Produkte vermarkten zu wollen, gab es da sehr lange einfach nichts und Free Pascal war verdammt spät dran. Ich nutze es immer noch gelegentlich, um mal schnell ein GUI-Dingsbums zusammenzuklicken, aber ich merke, dass das Ökosystem nachlässt.

Und ich würde zumindest Go und C# mal außen vor lassen. Die konkurrieren ja relativ wenig mit C und auch wenn Go am Anfang teilweise so vermarktet wurde ist das jetzt nicht die Sprache, wo man typischerweise mit C rangeht.

Scheinen die Verantwortlichen anders zu sehen:
https://golang.org/doc/faq#What_is_the_purpose_of_the_project

Auch wenn Java damals Leute von C/C++ umworben hat ist glaube ich der Bereich im Großen und Ganzen auch ziemlich getrennt mittlerweile und ich würde C# eher als Alternative zu Java ansetzen.

Ich stimme zu.
 
Weshalb der Rust-Sponsor Mozilla auch erst mal einen Webbrowser darin schreibt. Systemsoftware habe ich anders in Erinnerung.

Also ist C auch keine Systemsprache, weil es auch GUI-Anwendung gibt, die damit geschrieben sind? ;)

Wofür die Sprache, deren Compiler im Bestfall genau das tut, was man ihm aufträgt, exakt überhaupt nichts kann.

Zeige mir den perfekten Menschen der fehlerfreien C-Code produziert. Das Argument ist das gleiche wie mit den Waffen in den USA. Wir verkaufen frei Waffen, weil Waffen keine Menschen töten, sondern Menschen dies tun... Trotzdem will ich nicht, dass hier jeder mit einer geladenen Waffe rumläuft und ich _hoffe_ darauf, dass er nicht blöd ist. Ich bin dabei der leidtragende nicht der Täter.

Genauso ist das mit C-Code. Der Schaden tritt nicht beim Erschaffer auf, sondern bei den ganzen Opfern davon.
 
Zeige mir den perfekten Menschen, der fehlerfreien Rust-Code produziert.

Ach, das geht nicht? Weil es nicht an der Sprache liegt?
 
Zeige mir den perfekten Menschen der fehlerfreien C-Code produziert. Das Argument ist das gleiche wie mit den Waffen in den USA. Wir verkaufen frei Waffen, weil Waffen keine Menschen töten, sondern Menschen dies tun... Trotzdem will ich nicht, dass hier jeder mit einer geladenen Waffe rumläuft und ich _hoffe_ darauf, dass er nicht blöd ist. Ich bin dabei der leidtragende nicht der Täter.

Genauso ist das mit C-Code. Der Schaden tritt nicht beim Erschaffer auf, sondern bei den ganzen Opfern davon.

Ich denke dass dieser Vergleich hinkt. C ist keine Waffe für die man einen Waffenschein braucht. C ist ein Werkzeug um Programme zu schreiben.

C ist eher wie die Werkbank auf der das fehlerhafte Produkt produziert wird. Es soll eine Werkbank gebaut werden auf der keine fehlerhaften Produkte gefertigt werden können.

"Dann schreibt man das halt alles neu" ist genau der Ansatz den Yamagi zitiert hat:

Joel Spolsky schriebt vor inzwischen 17 Jahren darüber und der Text ist heute genauso aktuell wie damals: https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/

Ist das Problem nicht eher die inhärente Komplexität der Programme? Fuzzer finden ja auch viele Probleme indem sie Pfade durchspielen die so "normal" nicht durchlaufen werden.

Angenommen das wäre alles in Rust geschrieben, dann würde das Programm eben panic machen und abschmieren. Der rustc packt ja auch einfach Bound Checks ein (bsp, Buffer overflow). Als ich "das Buch" angefangen habe zu lesen sind mir auch gleich ein paar Sachen sauer aufgestossen:

cargo: Lädt automatisch Abhängigkeiten nach. Da krieg ich Pusteln. :zitter: Das ist doch das nächste Einfallstor. Ja es nutzt git. git nutzt sha1 und sha1 ist gebrochen.

Code:
Filename: src/main.rs

fn main() {
let x = (let y = 6);
}

When you run this program, you’ll get an error like this:

$ cargo run
Compiling functions v0.1.0 (file:///projects/functions)
error: expected expression, found statement (`let`)
--> src/main.rs:2:14
|
2 | let x = (let y = 6);
| ^^^
|
= note: variable declaration using `let` is a statement

The let y = 6 statement does not return a value, so there isn’t anything for x to bind to. This is different than in other languages, such as C and Ruby, where the assignment returns the value of the assignment. In those languages, you can write x = y = 6 and have both x and y have the value 6; that is not the case in Rust.

Ja warum kommt das Problem nicht zur Compilezeit und nicht erst zur runtime?
 
Zeige mir den perfekten Menschen, der fehlerfreien Rust-Code produziert.

Manchmal geht mir die Korinthenkackerei in diesem Forum echt auf den Sack...

Ach, das geht nicht? Weil es nicht an der Sprache liegt?

Standard-Fehler gehen in Rust durchaus nicht... also die Fehler die für einen Großteil der Lücken in C-Code verantwortlich sind. Aber das ignorierst du ja jedes mal feierlich....

Gut, ich lasse es an der Stelle auch. Es bringt eh nichts Argumente vorzubringen.
 
C ist eher wie die Werkbank auf der das fehlerhafte Produkt produziert wird. Es soll eine Werkbank gebaut werden auf der keine fehlerhaften Produkte gefertigt werden können.

In dem Argument ist dann aber die Werkbank so konstruiert, dass die Produkte eben nur schwierig fehlerfrei hinzubekommen sind ;) In dem Fall sollte mMn ebenfalls die Werkbank ausgetauscht werden und nicht der Arbeiter an der Werkbank, weil man meint er sei nicht fähig dazu fehlerfreie Produkte zu machen. edit: Also um mal die Diskussion von oben zu "untermauern". Du sagst ja das Gleiche.
 
Das Problem betrifft git übrigens nicht in dem Maße und auch git hat schon eine Vorkehrung dagegen getroffen.
Bei git soll ein neuer Commit Typ eingeführt werden welcher sha256 nutzt. sha1 ist aber tief in git verankert. Das wird sicher "schmerzhaft" das zu ändern. Es zeigt aber auch eines: Ein grosses Problem ist die Komplexität. Bei sha1 hat man sich halt lange darauf verlassen "wird schon passen. Es ist ein crypto Hash." Auf Schwächen von sha1 wurde schon lange hingewiesen aber auch in Projekten wie git wurde erst jetzt Gegenmassnahmen geplant.

Viele der Probleme die C mit den Buffer Overflows hat, lassen sich bsp. mit C++11 umgehen. std::array und range for loop. Keine rohen Pointer sondern shared/unique_ptr. std::array anstatt C arrays.

Ich denke nicht das C++ die reine Lehre ist. Ich kenne es gut. Es hat auch seine Schattenseiten. Jede Medaillie hat zwei Seiten. So ist es auch mit C und Rust und allen Programmiersprachen.

Ich denke dass wir die Komplexität besser in den Griff bekommen müssen. Es gibt genug Algorithmen (neuronale Netze) da ist debuggen praktisch nicht möglich. Man hat es trainiert und weis aber nicht genau wie es funktioniert. Man kennt die Funktion wie ein Neuron ein anderes stimuliert aber man versteht den Algorithmus den man dem Netz antrainiert hat nicht wirklich. Man trainiert es und testet es mit anderen Daten. Wenn das gewünschte raus kommt hofft man dass es immer so funktioniert. Ja ich habe zur Bilderkennung auch schon neuronale Netze eingesetzt (industrielle Bildverarbeitung). Hier ist das Feld noch ziemlich klein sowohl was Eingangs- und Ausgangsvektoren angeht.

Big Data anyone? Versteht hier jemand wie die Korrelationen gefunden wurden? Sind das wirklich ursächlich zusammenhängende Faktoren? Hier hilft uns keine andere Sprache, es hilft nur Wissen und verstehen und forschen. Oder wenn es nicht zu meistern ist, auch mal die Finger davon zu lassen. Das macht aber die Menschheit praktisch nie. Was gemacht werden kann, wird auch gemacht.

Geld ist zumeist einer der Gründe für schlechte Codequalität:
  • Time to market muss kleiner werden
  • Programmierer dürfen nicht viel kosten
  • Das Projekt muss schnell fertig werden.
  • Wenn der Autoupdate geht, wird verkauft.
  • etc....

Gruß
Georg
 
Bei git soll ein neuer Commit Typ eingeführt werden welcher sha256 nutzt. sha1 ist aber tief in git verankert. Das wird sicher "schmerzhaft" das zu ändern. Es zeigt aber auch eines: Ein grosses Problem ist die Komplexität. Bei sha1 hat man sich halt lange darauf verlassen "wird schon passen. Es ist ein crypto Hash." Auf Schwächen von sha1 wurde schon lange hingewiesen aber auch in Projekten wie git wurde erst jetzt Gegenmassnahmen geplant.

Also git will ja schon von SHA1 weg, klar. Aber es ist halt auch gerade echt nicht kritisch. Neben dem, dass du erst mal mittels verdammt viel Rechenleistung eine SHA1-Kollision erreichen musst, muss diese für git aber auch noch genau die gleiche Länge haben wie die alte Datei, da git ebenso die Dateilänge mit abspeichert und prüft. Und da hast du schon das: 1. überhaupt Hash-Kollision erzeugen für das Programm deiner Wahl (für die meisten Leute hier schon unmöglich) 2. diese Hash-Kollision auf die gleiche Länge bringen (zu 1 noch ein viel größeres Problem) 3. diese Hash-Kollision in das git-Repository kriegen (über einfachen git commit geht es schonmal nicht, müsste man sich erst mal zu github und Co. reinhacken).

Von daher ist SHA1 in git ne Sache von: "Kann man auf den Plan stellen, aber muss jetzt nicht alles andere dafür gestoppt werden".

Viele der Probleme die C mit den Buffer Overflows hat, lassen sich bsp. mit C++11 umgehen. std::array und range for loop. Keine rohen Pointer sondern shared/unique_ptr. std::array anstatt C arrays.

Ja, wenn man halt bei C++ an sich bleibt und auch Konstant diese Sachen aus dem std:: Part nimmt. Aber auch der [] Operator macht kein Bound-Check. Afaik nur die entsprechenden Getter-Funktionen tun dies, aber da bin ich mir auch nicht 100%ig sicher. Was Rust für sicher und unsicher hält kann man ja z.B. hier nachlesen: https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html

Aber ja, sicher in C++ programmieren ist ne Stufe einfacher als sicher in C programmieren. Schon aufgrund der Tatsache das C++ "native" Strings hat und somit im Alltag schon damit viele Probleme löst. Aber auch C++ ist in Systemsoftware nicht allzu weit verbreitet und die Standard Template Library wird allgemein als eher ungeeignet angesehen für viele Fälle, weshalb man diese dann auch oft nicht nimmt.
 
Jeder der sein Geld mit programmieren verdient weiß das man auch mit guten Programmiersprachen ziemlich viel Blödsinn schreiben kann.Solange Projekte nicht von Scratch entstehen ist das sinnlos darüber zu sinnieren ob C noch zeitgemäß ist. Ich empfinde C-Code sehr idiomatisch, C++ hingegen ist oft genug schwer zu entschlüsseln.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben