Frage zu cin
-
Warum funktioniert das?
int main() { char lBuf[2]; while(true) { cout << ">"; cin >> lBuf; cout << lBuf << endl; } }Ist sowas legitim? Oder ruft das Fehler hervor? (vermute ich jetzt mal)
Würde es halt gerne verstehen
-
Kannst du sagen, was du daran nicht verstehst? Ich muss erst neuen Kaffeesatz aufsetzen, bevor ich wieder Wahrsagen kann.
Der Code provoziert übrigens Fehler, wenn zwei oder mehr Nicht-Whitespace-Zeichen nacheinander eingegeben werden.
-
Das stimmt nicht, habe es gerade probiert und es wird kein Fehler produziert. So was nennt sich dann bloß undefiniertes Verhalten das nur fehleranfällig ist aber logisch gesehen ist der Code fehlerfrei und produziert auch nicht immer einen Fehler bei mehr als 2 Zeichen.
Bitte nicht schreiben wenn man es nicht wirklich verstanden hat, danke.
-

-
nööööö schrieb:
...So was nennt sich dann bloß undefiniertes Verhalten das nur fehleranfällig ist...
Der Satz ist ja mal geil, les dir den nochmal durch

Ist ja nicht so, als wäre undefiniertes Verhalten allein schon ein Fehler
Lg freeG
-
Kommt darauf an mit welchem Compiler du den Code compilierst, weil nicht jeder Compiler comipliert eine function die etwas zurück geben soll, dies jedoch nicht tut (return 0; in dem fall).
Das Porgramm ansich sollte funktionieren bis auf die Tatsache das nur maximal 2 chars in dein array eingelesen werden können und das ganze in einer Endloseschleife läuft.
-
HAWXthy schrieb:
Kommt darauf an mit welchem Compiler du den Code compilierst, weil nicht jeder Compiler comipliert eine function die etwas zurück geben soll, dies jedoch nicht tut (return 0; in dem fall).
Für main ists laut Standard erlaubt.
-
HAWXthy schrieb:
...weil nicht jeder Compiler comipliert eine function die etwas zurück geben soll, dies jedoch nicht tut (return 0; in dem fall).
int main ist eine Ausnahme. int main gibt, wenn man kein explizites return angibt, ein return 0 zurück.
-
edit: Doppelpost
-
HAWXthy schrieb:
Kommt darauf an mit welchem Compiler du den Code compilierst, weil nicht jeder Compiler comipliert eine function die etwas zurück geben soll, dies jedoch nicht tut (return 0; in dem fall).
In C++ ist die main-Funktion eine Ausnahme. Die gibt automatisch 0 zurück, wenn man nichts hinschreibt.
Das Porgramm ansich sollte funktionieren bis auf die Tatsache das nur maximal 2 chars in dein array eingelesen werden können und das ganze in einer Endloseschleife läuft.
Naja, man sollte aber noch erwähnen, dass vom istream bei der Operation auch noch ein Nullzeichen angehängt wird. Das muss auch noch in das Array passen (sonst wird es einfach dahinter geschrieben, wodurch wer weiß was überschrieben wird), also hat man effektiv nur Platz für ein eingegebenes Zeichen.
-
Das Programm ist jawohl definitiv fehlerhaft! Woher soll
cinwissen wie viele chars es in das Array schreiben darf? Wenn ich jetzt 3 Zeichen eingebe, dann wirdcinauch 3 Zeichen schreiben, also gibt es einen buffer overflow
. Verhindern könnte man das in diesem Fall indem man std::ios_base::width()verwendet (oderstd::setw()).
-
Oder std::string
-
Vielleicht habe ich mich etwas unverständlich ausgedrückt,
probiert den Code doch bitte mal aus.Hier wird devinitiv KEIN Fehler produziert. (Zummindest auf den 1. Blick nicht)
Egal ob man jetzt 5 oder 500 oder auch 5000 Zeichen eingibt,
bis jetzt gabs keine Speicherfehler oder sonst was.Eine Begründung wäre dass cin >> einfach über die array Grenzen
hinaus schreibt, jedoch in dem Fall nichts "wichtiges" überschreibt.Interessant ist halt immer noch dass ich es bis jetzt nicht geschafft
habe einen Fehler zu produzieren, egal wie viele Zeichen ich eingegeben
habe.
-
Du nutzt Microsoft Visual C++? Eventuell handelt es sich auch um ein Compiler Bug.
int main() { char buf[1]; buf[200] = 10; }Funktioniert. Kein Absturz.

int main() { int buf[1]; buf[200] = 10; }Funktioniert nicht. Absturz.

Eine Erklärung dafür habe ich jedenfalls nicht.
-
--- schrieb:
Du nutzt Microsoft Visual C++? Eventuell handelt es sich auch um ein Compiler Bug...
Nein, da es undefiniertes Verhalten ist, kann alles passieren (von nichts sichtbaren, bis zur Access Violation, dem Toasten deiner Festplatte...). Dies ist kein Compilerfehler, sondern beruht auf dem Designprinzip von C und C++.
Das ist genauso wie mit dem std::vector, der einmal den Indexoperator anbietet, und einmal die at-Methode. Die at-Methode prüft einen unerlaubten Indexzugriff, der Indexoperator muss dies aber nicht tun (und in den meisten Implementierungen die ich kenne, ist er auch ungeprüft).
C und C++ sind auf Performance ausgelegt, Prüfungen sind in der Regel optional (Wenn man dauernd durch riesige Arrays geht, macht sich eine Prüfung bei jeden Zugriff durchaus bemerkbar).
-
Den ersten Code habe ich auch mit dem g++ kompiliert und da gibt es keinen Fehler. Auch ein mehrmaliges Ausprobieren mit mehreren Zeichen konnte dem Programm keinen Fehler entlocken, irgendwann wird da sicherlich mal was überschrieben aber der Code an sich ist nicht fehlerhaft sondern nur fehleranfällig.
-
Das Verhalten ist undefiniert. Der C++-Standard definiert nicht, was in solchen Fällen passieren sollte, und sofern dein Compiler dafür keine eigene Semantik definiert (was er nicht tut), öffnest du dich damit für Merkwürdigkeiten aller Art.
Du schreibst in Speicher, der dir nicht gehört. Was dort liegt? Wer weiß - das wird von Compiler zu Compiler und von Betriebssystem zu Betriebssystem anders sein, und unter Umständen auch von Programmdurchlauf zu Programmdurchlauf. Es kann dir passieren, dass du einen Segfault bekommst. Es kann passieren, dass andere Variablen auf einmal merkwürdige Werte haben. Es kann dir passieren, dass du nach Beendigung der Funktion nicht an die aufrufende Stelle zurückkommst. Es kann dir passieren, dass ein nachfolgender Aufruf einer anderen Funktion sich seltsam verhält, dir beispielsweise die Festplatte formatiert.
Selbstverständlich ist so was fehlerhaft, und je eher du das in deinen Schädel kriegst, desto besser für dich und alle, die deine Programme benutzen wollen. Du kannst doch kein Programm so entwickeln, dass es vielleicht ab und zu das macht, was es soll.
Als nächstes behauptest du noch, ein Auto mit kaputter Bremsleitung sei nicht kaputt, sondern lediglich unfallanfällig.
-
Wie die viele Meldungen über Programmfehler aufzeigen, zeigen so gut wie alle C++ Programme undefiniertes Verhalten. Eine sichere C++ Anwendung mit definiertem Verhalten schaffen nicht mal die großen der Großen zu entwickeln und erst recht keiner hier im Forum.
-
defrgthz schrieb:
Wie die viele Meldungen über Programmfehler aufzeigen, zeigen so gut wie alle C++ Programme undefiniertes Verhalten.
Was für ein Schwachsinn. Fehler der Programmierer auf die Sprache zu schieben, ist jedenfalls nonsense. Sowohl C als auch C++ sind systemnahe Sprachen, und als solche dürfen sie eigentlich nicht zusätzliche Performace für Prüfungen die in vielen Fällen unnötig sind verlangen.
Wieso sollte beispielsweise bei jedem Zugriff der Index geprüft werden, wenn man in der Regel bereits von der Programmierseite einen fehlerhaften Indexzugriff ausschließen kann.
In C als auch C++ bezahlt man nur für das, was man auch will. Wenn man eine Indexüberprüfung braucht, schreibt man sich entweder eine, oder nimmt geprüfte Zugriffsmethoden (wie z.B. at() beim std::vector). Zudem ist ein std::string deutlich eher für cin-Eingaben unbekannter Größe geeignet als ein char-Array. Wenn man unbedingt mit char-Arrays arbeiten will soll man gefälligst auch die C-Methoden, ggf. die mit Indexprüfung verwenden.
defrgthz schrieb:
Eine sichere C++ Anwendung mit definiertem Verhalten schaffen nicht mal die großen der Großen zu entwickeln und erst recht keiner hier im Forum.
Wenn du Programmierfehler als Sprachfehler hinstellst, wird KEIN Programmierer eine Anwendung mit definierten Verhalten schaffen (Und auch Sprachen die Indexprüfungen durchführen, schützen nicht zwangsweise vor Fehlern. Beispiel NullPointerExceptions in Java-Programmen). Davon abgesehen das es Statistiken gibt das ungefähr 5% aller Codezeilen Fehler enthalten.
-
Wie du schon geschrieben hast sind ca. 5% eines jeden Programmcodes fehlerhaft. Nur ist das Problem bei C++ das hier die Fehler sehr üble Folgen haben können während sich bei Sprachen wie z.B. Java/C#/Python der Schaden meist nicht gleich in einem BufferOverflow bemerkbar macht.
Versteht du was ich damit sagen will?
Ich liebe die Systemsprachen auch über alles aber vom Sicherheitsaspekt sind sie Schrott. Da kannst du versuchen dich an alle Regel der Welt zu halten deine Anwedung wird fehlerhaft sein und bei C++ kann das ganz übel sein.
Aber so zum rumspielen mag ich die Sprache auch sehr, ist eine echte Herausforderung für jeden Programmierer.