Hallo wieso passiert das?Da ich schon ewig in Pascal schreibe aber immer
mal wieder ins C Lager schauen...erschrecken mich dann solche
Kommentare
"Da der freizügige Umgang der Programmiersprache mit dem Speicher in
kritischen Umgebungen (Kreditinstituten, Börsen, Versicherungen,
Raumfahrt usw.) leicht hohe Schäden nach sich ziehen kann, wird hier
mittlerweile ernsthaft erwogen, diese Programmiersprache bei neuen
Projekten zu verbieten."
Das zweite Beispiel zeigt was für Katastrophen beim Einsatz von c in der
Software einer Bank passieren können. Der Grundaufbau ist ähnlich wie
beim ersten Beispiel. Nur sind jetzt vier neue Variablen eingeführt
worden, welche den Kontostand, und das Aktiendepot eines Kunden
repräsentieren. Nach 14 Iterationen sind diese Variablen alle auf null
gesetzt, ohne daß man explizit auf diese Variablen zugegriffen hat.
Die Software hat die gesamten Einlagen des Kunden auf Null gesetzt, ohne
daß eine Transaktion statt gefunden hat.
Ist auch Ihre Kontoverwaltungssoftware in C geschrieben?
Quelle
http://www.wackerart.de/c.html
Schon mal in die Implementierung geschaut,
sprich wo C die automatischen Variablen anlegt?
Schon mal den Begriff Stack bzw. out of Arts bounds gehört?
Wer so programmiert, hat null Ahnung vom Konzept hinter C.
Nur weil es machbar ist, die Grenzen eines Arrays zu verletzen,
heißt das nicht, dass man dies auch tun sollte.
Naja das a-Array ist halt nur 10 Einträge groß. Wenn man nun auf das 11.
oder 30. Byte außerhalb des Arrays zugreift, ist nicht definiert was
dann passiert. Je nachdem was an dieser Speicherstelle liegt...
Hallo,
weil ein Array mit 10 Elementen angelegt wird:
int a[10];
Dann wird fleißig über diese Arraygrenze hinaus in der Gegend
rumgeschrieben:
a [c] = 0;
Natülich zerlegt das in C den Speicherinhalt. Das ist aber ein Problem
des C-Programmierers, der weiß nämlich, daß das passiert und wenn es
nicht passieren darf, wird er eine Abfrage einbauen, ob c größer als die
Array-Dimension ist und mit Fehler abbrechen.
Auch C-Programmierer sollten ihr Handwerk verstehen.
Insofern ist sowas gewollte Panikmache für mich.
Gruß aus Berlin
Michael
Tanja schrieb:> weil Int_max nicht definiert ist?
Nein, weil a mit länge 10 definiert ist und nicht mit INT_MAX.
Da wird Speicher überschrieben. Das kann auch in anderen Sprachen.
Programmieren muss man schon können.
In Pascal kann man auch irgend ein Speicher überschreiben, jedoch nicht
so einfach wie in C. Pascal würde erst einmal meckern mit einer
Exception und man muss schon einen besonderen Code programmieren um was
einfach so überschreiben zu können, z.B. den "move()" Befehl um Speicher
zu kopieren.
die Frage die sich mir stellt..warum gibt es überhaupt die Möglichkeit
auserhalb definierter Arrays zugreifen zu können?
ozu ist das gut?
Warum wird sowas nicht gleich beim Compilieren abgebrochen wie in
Sicherheitsbewussten Sprachen wie Ada oder PAscal?
Tanja schrieb:> Das zweite Beispiel zeigt was für Katastrophen beim Einsatz von c in der> Software einer Bank passieren können.
Weil Mist rauskommt, wenn man Mist programmiert? In welcher Sprache ist
das denn nicht so?
Rene H. schrieb:> Programmieren muss man schon können.
Richtig. Deshalb würde es vielleicht auch eher helfen, Programmierer,
die keine Ahnung haben, zu verbieten, als bestimmte Programmiersprachen.
Tanja schrieb:> Na in Pascal geht es nicht
Echt nicht? Bei den Pascal Entwicklungstools die ich kenne, konnte man
sich aussuchen, ob das "geht" oder nicht. (per "Range Checking" Option)
Tanja schrieb:> Warum wird sowas nicht gleich beim Compilieren abgebrochen
wenn der Index erst zur Laufzeit berechnet wird, dann kann das im
Allgemeinen beim Compilieren noch gar nicht erkannt werden.
ja, int Kontostand = 100000; ist zu groß, aber der Fehler wird in diesem
Fsll doch vom undefinierten Int_Max verursacht-oder?
Auch sowas ginge in Pascal/Ada nicht...
@Rolf Magnus
darum geht es ja! Um Programmierfehler..nicht ob jemand gut ist oder
schlecht
Klar, das Du Deine Programme alle Fehlerfrei schreibst glaubt dir ejder
ungesehen, aber vielen Pfeifen bei der Nasa oder MS oder Linux gelingt
das nun mal nicht. ;-)
> Nach 14 Iterationen sind diese Variablen alle auf null gesetzt, ohne daß> man explizit auf diese Variablen zugegriffen hat.
Abhängig von der Prozessorarchitektur könnte das hier auch einfach in
einer Endlosschleife resultieren oder in sonstwas.
Eine Endlosschleife gäbe es hier, wenn beim Stacküberlauf bei a[10] die
Laufvariable c mit 0 überschreiben würde...
Tanja schrieb:> ja, int Kontostand = 100000; ist zu groß
Nicht auf einem PC...
Tanja schrieb:> Ist auch Ihre Kontoverwaltungssoftware in C geschrieben?
Nein, in COBOL.
Übrigens muss das Verhalten gar nicht so sein, daß nach 15 Iterationen
die Variablen überschrieben wurden, deenn mancher C-Compiler optimierte
diese Kosntanten ganz vom stack weg, oder ordnet sie anders an, nicht
hinter dem Array a.
Ja, Arraygrenzenüberpüfung, ist halt nicht kompatibel mit Zeigern, und
eine Programmiersprache ohne Zeiger ist ... unpraktisch.
und bevorzugt der typische C coder eher die erste oder die zweite
Lösung?
if(A)
{
if(B)
printf("A and B\n");
}
else
printf("not A!\n");
oder
if(A) {
if(B) {
printf("A and B\n");
}
} else {
printf("not B!\n");
}
Schon lange nicht mehr so einen Bockmist gelesen. Da will wohl jemand
auf seine Website verlinken?
Tanja schrieb:> repräsentieren. Nach 14 Iterationen sind diese Variablen alle auf null> gesetzt, ohne daß man explizit auf diese Variablen zugegriffen hat.> Die Software hat die gesamten Einlagen des Kunden auf Null gesetzt, ohne> daß eine Transaktion statt gefunden hat.> Ist auch Ihre Kontoverwaltungssoftware in C geschrieben?
Schonmal Kontoverwaltungssoftware/Bankensoftware zu Gesicht bekommen?
Ich habe letztens einen Vortrag von itestra gehört. Die meiste
Bankensoftware (also der Teil, der wirklich Buchungen vornimmt, also mit
Geld arbeitet) ist in COBOL geschrieben. COBOL! Das habe ich jetzt schon
von mehreren ernstzunehmenden Personen (Professoren, Firmeneigentümer,
SW-Entwickler für solche SW) gehört und glaube es.
COBOL hat eine schreckliche Syntax und erlaubt auch jede Menge Fehler,
trotzdem läuft der Scheiß. Warum?
Weil man testet und versucht durch eine vernünftige Qualitätssicherung
solche Fehler abzustellen. Außerdem lässt man nicht jeden Depp an die
Materie ran(vermutlich der größte Qualitätssicherungssschritt). Nur so
zur Panikmache ggü. der Kontoverwaltungssoftware...
Zu C:
Ja C hat viele Eigenheiten, Besonderheiten und Fallstricke.
Gehen wir nochmal auf Sicherheitsrelevante Probleme ein: Automobil,
Flugzeug, Zug.
Ich kann jetzt nur für die SW Entwicklung im Automobil sprechen:
ALLE Projekte, die ich bis jetzt gesehen hab, sind in C implementiert.
Sogar (der "fortschrittlichste" Autobauer der Welt) Tesla implementiert
in C. Man muss sowieso testen, egal welche Sprache man benutzt. Dabei
fallen solche Dinge auf, wie das hier gezeigte Beispiel.
Gerade für C haben sich in all den Jahren so unglaublich viele Tools
entwickelt, die versuchen, auf Ungereimtheiten im Quellcode hinzuweisen.
Und das funktioniert i.d.R. ganz gut.
In C hat man unglaublich viel Freiheit, damit kommt auch Macht einher.
Diese muss man halt wissen einzusetzen, aber das ist bei jeder
Programmiersprache so.
P.S.:
sogar moderne Programmmiersprachen wie Python erlauben, wenn der
Interpreter Fehler hat, das manipulieren von Speicher. Fehler gibt es
immer und überall in SW, man muss diese halt finden!
Tanja schrieb:> und bevorzugt der typische C coder eher die erste oder die zweite> Lösung?
Programmierstil ist in Sprachen ohne festgelegter Zeilen/Spaltenstruktur
eher Konvention als Sprachdefinition. Ob du begin/end in die gleichen
oder in separate Zeilen packst, oder in unnötigen Fällen ganz weglässt,
interessiert den Pascal-Compiler auch nicht.
Pascal ist in dieser Frage syntaktisch weitgehend wie C, nur bei
trennendem vs. abschliessendem Semikolon unterscheidet es sich hier.
Anders sieht es hingehen bei Sprachen mit if...else...endif aus.
Generell bei solchen Sprachen, die Blöcke nicht mit explizitem {...}
oder begin...end bilden, sondern implizit.
Auch in COBOL und nebenbei auch in PL/1 sind Indexüberschreitungen
möglich. Sie gehören zu den unangenehmsten Fehlern.
Wer das vermeiden will, sollte in ADA schreiben.!
@Axeleetc)schön wäre wenn man endlich seinen eigenen Threads Moderieren
könnte um störende Beiträge einfach löschen zu können..
JA, in Pascal kann man diese Überprüfung abschalten..aber das ist nicht
die Frage gewesen, interessanter ist die Antwort das man bei
manchen....(da gehts schon wieder los ;-) Compilern in C so eine
Überprüfung einschalten kann..
Aber z.B. bei vielen tools zur Microcontroller Programmierung geht das
ben nict (Mikroe z.B)
@MaWin
In welcher Sprache gibt es denn keine Zeiger?
Selbst Bscom verfügt meines Wissens nach darüber..
Tanja schrieb:> @MaWin> In welcher Sprache gibt es denn keine Zeiger?> Selbst Bscom verfügt meines Wissens nach darüber..
Ich bin zwar nicht MaWin, aber Antwort: Java z.B.
Tanja schrieb:> @Axeleetc)schön wäre wenn man endlich seinen eigenen Threads Moderieren> könnte um störende Beiträge einfach löschen zu können..>> JA, in Pascal kann man diese Überprüfung abschalten..aber das ist nicht> die Frage gewesen, interessanter ist die Antwort das man bei> manchen....(da gehts schon wieder los ;-) Compilern in C so eine> Überprüfung einschalten kann..> Aber z.B. bei vielen tools zur Microcontroller Programmierung geht das> ben nict (Mikroe z.B)>> @MaWin> In welcher Sprache gibt es denn keine Zeiger?> Selbst Bscom verfügt meines Wissens nach darüber..
Java.
Ist robuster als alle C und Pascal zusammen.
Tanja schrieb:> @Rolf Magnus> darum geht es ja! Um Programmierfehler..nicht ob jemand gut ist oder> schlecht
Mir geht es um beides, vorrangig um das zweite. Das wichtigste, um
Fehler zu vermeiden, ist meines Erachtens, zu wissen, wie man sie
vermeidet und nicht, ein Tool zu haben, das versucht, die Fehler des
Programmierers wieder irgendwie geradezubiegen.
Dein Beispiel würde in einigen anderen Sprachen vielleicht nicht wahllos
Speicher überschreiben, aber auf magische Weise das gewünschte statt das
programmierte wird dort auch nicht passieren.
Tanja schrieb:> und bevorzugt der typische C coder eher die erste oder die zweite> Lösung?> if(A)> {> if(B)> printf("A and B\n");> }> else> printf("not A!\n");>> oder>> if(A) {> if(B) {> printf("A and B\n");> }> } else {> printf("not B!\n");> }
Nun, ich würde eine dritte Variante bevorzugen, aber wenn ich zwischen
den zweien wählen sollte, definitiv die erste. Die zweite sieht meinem
Empfinden nach aus wie Kraut und Rüben. Für mich gehört die öffnende
geschweifte Klammer auch grundsätzlich in die selbe Spalte wie die
schließende, und genau wie diese in eine eigene Zeile. Dadurch kann man
die Struktur des Programms viel leichter erfassen, da man
zusammengehörende Klammern viel schneller auch einander zuordnen kann.
Das hat aber nicht wirklich was mit der Sprache zu tun.
C ist eine Sprache für Programmierer, die wissen was sie tun:
Freeclimbing
Pascal ist eine Lehrsprachezum für Anfänger: Laufstall
Wenn ich vom Felsen runter falle tuts weh. Ja, isso.
Tanja schrieb:> Aber z.B. bei vielen tools zur Microcontroller Programmierung geht das> ben nict (Mikroe z.B)
Ich dachte es ging um Banken-Software? Was sucht die auf einem µC? Und
was soll das µC-Programm tun, wenn es eine solche Überschreitung
festgestellt hat? Einfach stehen bleiben? "out-of-range exception"?
Da ich schon ewig in deutsch schreibe und immer wieder fremde Texte
lese, erschrecken mich dann solche Texte:
Tanja schrieb:> Hallo wieso passiert das?Da ich schon ewig in Pascal schreibe aber immer
zwei fehlende Kommas, ein fehlendes Leerzeichen
> mal wieder ins C Lager schauen...erschrecken mich dann solche
ein fehlender Bindestrich
> Kommentare
ein fehlender Doppelpunkt
Sieht Dein Pascal-Quellcode genauso aus wie Deine deutsche
Schriftsprache?
Urheberrecht ist irgendwie auch nicht Deine Stärke?
>Hallo, wieso passiert das?
Vermutlich läuft der Index c über und wird negativ.
Der negative Offset c führt dann via a [c] = 0 zum Überschreiben der
davor im Speicher liegenden Variablen.
Es ist wunderschön, wie sich Klein-Erna Software-Produkte in "kritischen
Bereichen" vorstellt.
Kritisch ist für mich die nicht genannte Medizintechnik und auch die
Raumfahrt wegen der damit verbundenen Menschenleben.
Software in Banken, Börsen und Versicherungen sind aus meiner Sicht
wichtig, aber nicht kritisch.
Im obigen Beispiel liegt der Quellcode offen und die Programmiersprache
ist auch noch in Gebrauch, wo soll denn da ein Problem sein?
Man stelle sich vor, eine der genannten Institutionen nutzt Software, wo
der Quellcode nicht offenliegt, der Hersteller nicht mehr existiert und
die Programmiersprache, in der der Quellcode verfasst wurde, ist auch
nicht mehr im Gebrauch. Eventuell wurde der Quellcode auch gleich in
Maschinensprache geschrieben.
Die abartigen Fantasien abschlussorientierter Firmenkundenbetreuer führt
zu Auswüchsen bei Kreditverträgen, die man in Software nur schwer
nachbilden kann.
Heutige Kontoverwaltungssoftware für Banken in der aktuellsten Version,
die auch gleich Kredite mitverwaltet, kann kein Unicode.
Sie scheitert schon an einem "ß" im Kommentarfeld.
Es scheint, dass Programmierer mindestens das Komplexitätsverständnis
von Elektrotechnikern haben müssen, um Software zu schreiben, die
saubere Tilgungspläne für Kredite zu erstellen.
In obigen Institutionen gibt es eine Vielzahl von individuellen
Software-Lösungen auf Office/Excelbasis, die von engagierten Laien
geschrieben wurde.
Der Umfang dieser Software wächst, sie wird aber nie auf eine stabile
Plattform portiert, bzw. professionalisiert.
In Analogie zu Frickellösungen beim Auto "Prestolith und Fliegendraht
halten auch bei schneller Fahrt" leben Provisorien in den oben genannten
Firmen länger.
Eine für sich einigermaßen gute Software wird in ein Ökosystem mit
sogenannten "Altsystemen" eingepflanzt. Budget gibt es für die neue
Software, also wird die neue Software "passend gemacht".
Mit der Anpassung an Altsysteme verliert die neue Software Stabilität
und gute Eigenschaften.
Wir schreiben das Jahr 2016, aber von der Softwarequalität her sind wir
weit in der Vergangenheit stehengeblieben.
Tanja schrieb:> @Axeleetc)schön wäre wenn man endlich seinen eigenen Threads Moderieren> könnte um störende Beiträge einfach löschen zu können..>> JA, in Pascal kann man diese Überprüfung abschalten..aber das ist nicht> die Frage gewesen, interessanter ist die Antwort das man bei> manchen....(da gehts schon wieder los ;-) Compilern in C so eine> Überprüfung einschalten kann..> Aber z.B. bei vielen tools zur Microcontroller Programmierung geht das> ben nict (Mikroe z.B)>> @MaWin> In welcher Sprache gibt es denn keine Zeiger?> Selbst Bscom verfügt meines Wissens nach darüber..
Es könnte damit zusammenhängen das für eine Array-Grenzenüberprüfung
sowohl zusätzlicher Speicher als auch zusätzliche Laufzeit notwendig
ist.
Mikrocontroller haben von ersteren nicht so viel.
Wenn der Programmierer nach Anlegen eines Arrays beim Nutzen im
fortlaufenden Code sich nicht mehr sicher ist,kann er sich ja selbst die
Array-Grenzen-Prüfung einbauen.
C ist keine Lernsprache.
Damals [tm] war Speicher auch noch knapp und
C soll auch nicht zur Laufzeit die eigene Vergesslichkeit des
Programmierers ausgleichen.
Pointer-arithmetik und casten in Zeigern auf kleiner Stukturen würde den
Wasserkopf der Arraygrenzenprüfung sicher auch anschwellen lassen.
Dirk B. schrieb:> C ist eine Sprache für Programmierer, die wissen was sie tun:> Freeclimbing> Pascal ist eine Lehrsprachezum für Anfänger: Laufstall>> Wenn ich vom Felsen runter falle tuts weh. Ja, isso.
Das hinkt aber gewaltig. So denkt ein Freeclimber, aber keine
börsennotierte Firma, die Ruf, Kunden, Unternehmenwert zu verlieren hat.
Der Freeclimber ist nur selber tot, eine Firma, die Zuviel Risiko bei
der Software eingeht verursacht evtl großen Schaden, und wenn er nur der
eigene Untergang ist.
Eine solche Firma wird nicht für waghalsige Artistik von der Börse
belohnt, sonder für solide Lösungen.
Der GCC gibt mit zu dem Code eine Warnung aus:
123.c:18:13: warning: iteration 10u invokes undefined behavior
[-Waggressive-loop-optimizations]
a [c] = 0;
Den GGC rufe ich als Funktion auf, mit Parametern die praktisch immer
passen:
function c {
gcc -Wall -fbounds-check -fstack-protector -D_FORTIFY_SOURCE=2 -I. -O5
\
-D_GNU_SOURCE -D__SMP__ -DLINUX -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS
\
-D_REENTRANT -std=gnu99 -lpthread -lncurses -lrt -funroll-loops -mmmx \
-m3dnow -ftracer -fexpensive-optimizations -ffast-math
-Wno-unused-result \
-o $1 $1.c -lz -lm && strip $1 && chmod +t $1
}
Ich würde sagen, der Thread ist unsinnig, wenn man uCs miteinbezieht.
Da muss man hardwarenah bleiben um Ressourcen zu sparen und Performance
zu erreichen.
Aber bei Bankensoftware kann man mal von ausreichend CPU und RAM
ausgehen und der entscheidende Wert ist Robustheit. Für die man sich
deshalb beliebig viele Resourcen leisten kann. -> Java.
Conny G. schrieb:> Aber bei Bankensoftware kann man mal von ausreichend CPU und RAM> ausgehen und der entscheidende Wert ist Robustheit. Für die man sich> deshalb beliebig viele Resourcen leisten kann. -> Java.
Das ist korrekt. 64 Quadcores und 512 GB ist bei uns Standard.
Nur, wenn Highperformance gefragt ist, wird immer noch in C++
programmiert.
(obwohl das bald kein Argument mehr sein dürfte).
Conny G. schrieb:> Ich würde sagen, der Thread ist unsinnig, wenn man uCs miteinbezieht.> Da muss man hardwarenah bleiben um Ressourcen zu sparen und Performance> zu erreichen.> Aber bei Bankensoftware kann man mal von ausreichend CPU und RAM> ausgehen und der entscheidende Wert ist Robustheit. Für die man sich> deshalb beliebig viele Resourcen leisten kann. -> Java.
Nein!
In den Genuss von ausreichend CPU,RAM und toleranten Sprachen kommen nur
Neuentwicklungen.
Dies gilt aber eben nicht für die Altsysteme. Bitte auch die mehrfachen
realistischen Hinweise in den anderen Beiträgen auf Cobol beachten!
Peter M. schrieb:> Dies gilt aber eben nicht für die Altsysteme. Bitte auch die mehrfachen> realistischen Hinweise in den anderen Beiträgen auf Cobol beachten!
Legacy Software gibt es immer, die werden aber üblicherweise abgelöst
(ausser den Host, den kriegt man kaum los).
Sowas schreibt einfach kein Programmierer, der bei Verstand ist.
In C ist man für das Abfangen von derart groben Schnitzern selber
verantwortlich.
Man könnte z.B. schreiben:
1
if(c<sizeof(a)/sizeof(a[0])){
2
a[c]=0;
3
}else{
4
printf("Programmierer war besoffen oder stoned!\n");
Ich möchte zunächst nochmal betonen, dass zu dem Beispielcode auch das
Java- oder Pascal-Pendant fehlerhaft ist, wenn man versucht, über die
Array-Grenzen hinaus zu schreiben. Der Fehler verschwindet nicht durch
Wechsel der Sprache. Der einzige Unterschied ist, dass die Reaktion auf
diesen Fehler in der Sprache definiert ist. Bei Java schmiert das
Programm dann eben mit einer Exception ab. Die könnte man natürlich
abfangen, aber was kann man dann noch sinnvolles machen? Der Algorithmus
ist irgendwo mittendrin unterbrochen worden. In welchem Zustand diese
halbfertigen Daten jetzt sind, weiß man auch nicht sicher. Also hat man
in meinen Augen jetzt nicht so wahnisnnig viel gewonnen.
Peter M. schrieb:> In obigen Institutionen gibt es eine Vielzahl von individuellen> Software-Lösungen auf Office/Excelbasis, die von engagierten Laien> geschrieben wurde.> Der Umfang dieser Software wächst, sie wird aber nie auf eine stabile> Plattform portiert, bzw. professionalisiert.
Das ist auch ein Problem, ja. Da wird irgendwas von Leuten geschrieben,
die keine Programmierer sind und sich das Programmieren dabei nebenher
beibringen. Das wächst dann über die Jahre immer weiter, bis es zu einem
Codemonster geworden ist. Es hat jede Menge Bugs, die aber jeder kennt
und die man bei der Benutzung irgendwie umschifft. Das ist
fehlerträchtig und erzeugt Mehraufwand. Die daraus entstehenden
Zusatzkosten werden aber nirgends explizit erfasst, daher interessiert
sich das Management nicht dafür. Wenn man es in richtig nochmal neu
schreiben würde, wäre es zu teuer - nicht weil es mehr kosten würde,
sondern weil die Kosten da als große Zahl schwarz auf weiß stehen. Und
an dem Codemonster die Bugs rausmachen geht auch nicht, weil das keiner
mehr anfassen will. So lebt man jahrelang mit einer von einem Amateur
zusammengefrickelten Notlösung und wundert sich, dass das nix taugt.
Conny G. schrieb:> Eine solche Firma wird nicht für waghalsige Artistik von der Börse> belohnt, sonder für solide Lösungen.
Mir scheint es eher, dass gerade die waghalsige Artistik bei der Börse
am stärksten belohnt wird - wenn auch nicht unbedigt bei der benutzten
Software.
Rene H. schrieb:> Peter M. schrieb:>> Dies gilt aber eben nicht für die Altsysteme. Bitte auch die mehrfachen>> realistischen Hinweise in den anderen Beiträgen auf Cobol beachten!>> Legacy Software gibt es immer, die werden aber üblicherweise abgelöst
Wird sie? Ich hab den Eindruck, dass "üblicherweise" jeder weiß, dass
sie abgelöst gehört, aber dass es viele viele Jahre dauert, bis dann
tatsächlich was passiert.
Rolf M. schrieb:> Ich möchte zunächst nochmal betonen, dass zu dem Beispielcode auch das> Java- oder Pascal-Pendant fehlerhaft ist, wenn man versucht, über die> Array-Grenzen hinaus zu schreiben. Der Fehler verschwindet nicht durch> Wechsel der Sprache. Der einzige Unterschied ist, dass die Reaktion auf> diesen Fehler in der Sprache definiert ist. Bei Java schmiert das> Programm dann eben mit einer Exception ab. Die könnte man natürlich> abfangen, aber was kann man dann noch sinnvolles machen? Der Algorithmus> ist irgendwo mittendrin unterbrochen worden. In welchem Zustand diese> halbfertigen Daten jetzt sind, weiß man auch nicht sicher. Also hat man> in meinen Augen jetzt nicht so wahnisnnig viel gewonnen.
Doch man gewinnt etwas: die Integrität der Daten (in dem Fall die
Kontostände) bleibt erhalten. Und ja, ich weiß dass es nur ein paar
Daten im RAM sind, aber es geht hier in diesem Beispiel um das
grundsätzliche Problem, welches bei C nun mal besteht. In einer realen
Applikation kann so ein Speicherschreiber beliebige andere Katastrophen
auslösen, die beim Werfen einer Exception eben NICHT entstehen können.
Selbst wenn das Programm gar nichts mit der Exception anzufangen weiß
und sich beendet, dann ist das - z.B. bei einer Serveranwendung - immer
noch besser, als einfach irgend wie weiter zu machen und einem möglichen
Angreifer mit eben so einem Speicherschreiber ein Einfallstor zu bieten.
Im übrigen bin ich der Meinung, dass diejenigen, die hier im Thread ganz
laut schreien, dass nur schlechte Programmierer solche Klöpse bauen,
weil es ja gaaaaaaanz klar ist, dass sowas Probleme macht, die
allerersten sind, die genau solche Fehler machen. Nur weil es in diesem
Beispiel ganz offensichtlich ist, warum das schief geht, heißt das noch
lange nicht, dass nicht ähnliche Fehler in komplexen Programmen nicht
genau so gut möglich sind - nur halt wesentlich versteckter. Da genügt
ein einzelnes strcpy() statt einem strncpy() und schon ist das Problem
da.
Axel S. schrieb:> .--------------------------------.> |Die Trolle bitte nicht füttern. |> | Sie bekommen sonst Durchfall. |> | An beiden(!) Enden. |> `--------------------------------´
Passt dazu:
MaWin schrieb:> Ja, Arraygrenzenüberpüfung, ist halt nicht kompatibel mit Zeigern, und> eine Programmiersprache ohne Zeiger ist ... unpraktisch.
Mir fällt auf Anhieb keine Situation ein, die man nicht auch ohne
Pointer lösen könnte.
Niemand muß mit Gewalt für sämtliche Anwendungen C benutzen, kein Deckel
paßt auf alle Töpfe.
Wer damit leben kann, daß nicht ständig aller Tod und Teufel umständlich
zur Laufzeit geprüft wird, der wird C lieben.
Viele C Compiler können außerdem schon zur Compilezeit vor
Indexüberschreitungen und anderen Programmierfehlern warnen. Es wird
nicht mehr nur die Syntax geprüft.
Als ich damals auf dem 12MHz/286-er PC ein Programm von Turbo-Pascal auf
Turbo-C umgeschrieben hatte, war der Geschwindigkeitszuwachs schon sehr
beeindruckend.
Frank B. schrieb:> MaWin schrieb:>> Ja, Arraygrenzenüberpüfung, ist halt nicht kompatibel mit Zeigern, und>> eine Programmiersprache ohne Zeiger ist ... unpraktisch.>> Mir fällt auf Anhieb keine Situation ein, die man nicht auch ohne> Pointer lösen könnte.
Ja, aber manche Funktionen verlangen Pointer, z. B. qsort(), und auch
das Arbeiten mit Filepointern ist üblich.
Solange man Pointer nur für solche Fälle verwendet und nicht wild
rumrechnet, hat man mit Pointern praktisch nie Probleme. Zumindest nicht
wenn man Rückgabewerte überprüft.
Sonst hat man Klingonen-Code, der gnadenlos auch Nullpointer
verarbeitet.
C ist ursprünglich zum Schreiben von Betriebssystemen entwickelt worden
und Leute, die derlei Jobs haben, wissen in aller Regel, was sie tun.
Buchhaltungsprogramme kann man damit schreiben, aber diese Sprachwahl
würde ich doch als ziemlich unglücklich bezeichnen und wenn man sieht,
was für Programmier-Cracks auf dem Gebiet ihr Unwesen treiben, wäre sie
sogar ein grober Kunstfehler.
Mit C++ kann man Container definieren, die all diese Depperlntests
automatisch machen. Das Problem ist nur, dass die Sprache derartig
mächtig ist, dass man ein umgeschulter Buchhalter damit mindestens so
viel Unheil anrichten kann, wie mit C.
Denen gibt man lieber Cobol an die Hand, da weiß man, dass vor allem mit
Tippen beschäftigt sind...
Rolf M. schrieb:> Wird sie? Ich hab den Eindruck, dass "üblicherweise" jeder weiß, dass> sie abgelöst gehört, aber dass es viele viele Jahre dauert, bis dann> tatsächlich was passiert.
Natürlich hast Du recht, wird sie erst, bis der Manager erkannt hat,
dass muss jetzt sein. Und dann braucht es noch mindestens 5 Versuche bis
zum Erfolg. Den Grund kennst Du sicher dafür auch. Das ist hier aber
nicht Thema (Gott sei dank).
Tanja schrieb:> @Axeleetc)schön wäre wenn man endlich seinen eigenen Threads Moderieren> könnte um störende Beiträge einfach löschen zu können..
Falls du mich gemeint hast: ich habe dich gemeint.
Du bist der Troll.
[x] geh weg
A. K. schrieb:> Axel S. schrieb:>> *Leute!*>> Wär dir ein C vs Assembler Troll-Thread wirklich lieber? ;-)
Mir wäre es lieber, wenn alle Trolle verhungern würden.
Immerhin ist der Thread ja schon in "Offtopic" gelandet.
Kaj G. schrieb:> Rene H. schrieb:>> Den Grund kennst Du sicher dafür auch.> ...eine strikte Trennung von Verantwortung und Kompetenz ;)
Yep :). Genau so.
Frank B. schrieb:> Mir fällt auf Anhieb keine Situation ein, die man nicht auch ohne> Pointer lösen könnte.
Ohne Pointer würde fast garnichts laufen. Weder könnten Arrays
bearbeitet noch Objekte aufgerufen werden. Auch wenn man bei Arrays die
Schreibweise mit Index bevorzugt, der Compiler macht Pointer daraus.
Es gibt Sprachen, die die Pointer verstecken oder anders nennen, oder
die Arithmetik mit Pointern verbieten nach dem Motto "Messer, Gabel,
Pointer, Licht sind für kleine Kinder nicht". Aber für anspruchsvollere
Aufgaben sind sie unpraktisch, wie Mawin schon sagte.
Jobst Q. schrieb:> Ohne Pointer würde fast garnichts laufen. Weder könnten Arrays> bearbeitet noch Objekte aufgerufen werden. Auch wenn man bei Arrays die> Schreibweise mit Index bevorzugt, der Compiler macht Pointer daraus.
Pointer im hier betrachteten Sinn sind Konstruktionen bestimmter
Hochsprachen. In die Zielsprache macht ein Compiler Adressrechnungen
daraus. Je nach Maschine und Sprachkonstrukt sind diese explizit oder
implizit.
Diese beiden Konzepte kann man zwar in eine Topf werfen, und in C ist
das in gewisser Weise der Fall, aber ich finde es hilfreicher, die
Hochsprachen und ihre Implementierung auf der Zielmaschine auseinander
zu halten. Andernfalls kommt man jenen entgegen, die C als
High-Level-Assembler bezeichnen.
> Es gibt Sprachen, die die Pointer verstecken oder anders nennen, oder> die Arithmetik mit Pointern verbieten nach dem Motto "Messer, Gabel,> Pointer, Licht sind für kleine Kinder nicht". Aber für anspruchsvollere> Aufgaben sind sie unpraktisch, wie Mawin schon sagte.
C erleichtert es dem Programmierer erheblich, sich daran selbst
aufzuhängen. Das kann in bestimmten Anwendungen auch erforderlich sein.
Beispielsweise dann, wenn darin Daten von höheren darin nicht sichtbaren
Anwendungsebenen verarbeitet werden. Wie etwa in Betriebssystemen und
Devicedrivern.
Oftmals ist es aber in der Programmierung auf Anwendungsebene letzlich
sinnvoller, dem Programmierer bestimmte Fesseln anzulegen. Nicht weil
das so effizienter wird, sondern weil daraus bessere und sicherere
Programme erwachsen.
Tanja schrieb:> a [c] = 0;
Ein Auto hindert einen auch nicht, unangeschnallt gegen eine Wand zu
fahren.
Ist deshalb das Auto schlecht oder doch eher der Fahrer?
Peter D. schrieb:> exit(-1);
man exit
$ cat exit.c
#include <stdlib.h>
int main ()
{
exit(-1);
}
$ cc exit.c -o exit && ./exit
$ echo $?
255
Frank M. schrieb:> Ein Auto hindert einen auch nicht, unangeschnallt gegen eine Wand zu> fahren.
Und was viele unterschätzen: es hindert einen auch nicht, angeschnallt
gegen eine Wand zu fahren...
Lothar M. schrieb:> Und was viele unterschätzen: es hindert einen auch nicht, /angeschnallt/> gegen eine Wand zu fahren...
Wobei manche Fahrzeuge in beiden Fällen warnen. Also wenn nicht
angeschnallt und wenn zu nahe an Hindernissen dran.
Manch eingefleischter C Programmierer fäht aber sicherlich lieber einen
alten VW-Käfer. Von jener Sorte, deren Lenksäule sich bei einem Unfall
in den Fahrer bohrt. Soll angeblich zu verantwortungsvollen Fahren
verleiten. Und sei es durch Darwins Auslese.
A. K. schrieb:> Von jener Sorte, deren Lenksäule sich bei einem Unfall> in den Fahrer bohrt.
C-Programmierer leben da an ihrem Rechner ungefährlicher.
> Soll angeblich zu verantwortungsvollen Fahren verleiten.
Hier fehlt mir das Äquivalent. Stromstöße vom PC? ;-)
Frank M. schrieb:>> Soll angeblich zu verantwortungsvollen Fahren verleiten.>> Hier fehlt mir das Äquivalent. Stromstöße vom PC? ;-)https://xkcd.com/371/
Einen kleinen Satz möchte ich hier noch zitieren:
von http://www.bernd-leitenberger.de/echte-programmierer.shtml
"Hier eine Liste der wichtigsten Programmierhilfen, die der Echte
Programmierer nicht benutzt:"
-Compiler, die Code für Array-Indexprüfung zur Laufzeit erzeugen. Sie
ersticken jede Kreativität, zerstören die meisten der interessanteren
Anwendungen der EQUIVALENCE-Vereinbarung, und machen Änderungen des
Betriebssystems mittels negativer Indizes unmöglich. Und, schlimmer
noch, solcher Code ist ineffizient."
Lothar M. schrieb:> A. K. schrieb:>> Wobei manche Fahrzeuge in beiden Fällen warnen.> Manche Compiler tun das durchaus auch...
Aber wen juckt das schon.
Warnung ist ja kein Fehler und notfalls postet man hier:
"völlig unverständliches Verhalten des C-Compilers", dabei hat der
"Warning: don't do xyz" gesagt.
Solange es noch Warnings gibt, hat man die Anweisungen an den Compiler
nicht zweifelsfrei beschrieben.
Das gilt erst mal sehr, sehr lange. Und dann weiß man auch schon, was
man tut.