Verhalten von fcloseall und dessen Einsatzgebiet
-
@RBS2 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
@Wade1234 sagte in Umgangston:
witzig, dass wir hier in einem thread, der davon handelt, dass der umgangston schlecht ist, irgendwas ausdiskutieren und der umgangston dabei schlecht ist.
Was lernen wir daraus? Also trotz allen Gepöbels immer cool bleiben. Guter Thread!
Oder auch dass man ruhig erstmal nachfragen kann, wenn...
- jemand irgendwo sagt "X hat in sauberer Software nix verloren" und
- man irgendwie nicht so ganz versteht warum/das nicht so sieht und
- man nicht so genau weiss was X eigentlich ist/tut
...bevor man anfängt ihn darüber zu belehren dass man das auch anders sehen kann.
-
@hustbaer sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
ps: Mir fällt gerade auf, du könntest "gleiches Verhalten" auch auf dein Testprogramm bezogen haben, wo du der Einfachkeit halber den NULL Check weggelassen hast. In dem Fall ja, klar, vermutlich gleiches Verhalten. Nur halt nicht gleiches Problem in realer Software, da 1x problemlos behandelbar und 1x totale Katastrophe.
ja das war auch auf mein (windows-) testprogramm bezogen.
unter freebsd stürzt da übrigens nichtmal was ab, das programm läuft ganz normal. die schreiboperation nach log.txt erfolgt, weil der stdout ja geschlossen ist. edit: moment, da stimmt irgendwas mit der ausgabe nicht. ich erhalte n == 5 und errno 9 (ungültige datei). bug im compiler?
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> #include <string.h> int main() { int file; int n; char str[100]; char str1[100]; char str2[100]; file = open("test.txt", O_RDWR | O_CREAT); if(file == -1) { printf("open failed\n"); return 1; } fcloseall(); //close(file); n = write(file, "test", 5); close(file); file = open("log.txt", O_WRONLY); sprintf(str1, "%d bytes written.\n", n); write(file, str1, strlen(str1) + 1); if(n <= 0) { sprintf(str2, "errno: %d\n", errno); write(file, str2, strlen(str2) + 1); } close(file); return 0; }
-
@Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
unter freebsd stürzt da übrigens nichtmal was ab, das programm läuft ganz normal. die schreiboperation nach log.txt erfolgt, weil der stdout ja geschlossen ist. edit: moment, da stimmt irgendwas mit der ausgabe nicht. ich erhalte n == 5 und errno 9 (ungültige datei). bug im compiler?
Das könnte damit zu tun haben dass undefiniertes Verhalten undefiniertes Verhalten ist.
-
undefiniertes verhalten bedeutet doch, dass man die bedienungsanleitung des compilers lesen soll, oder nicht?
-
@Wade1234
Nö, undefiniertes Verhalten bedeutet, dass das Programm machen darf, was es will, und der Compiler trotzdem alles richtig gemacht hat. Nur halt der Programmierer nicht.
-
@Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
undefiniertes verhalten bedeutet doch, dass man die bedienungsanleitung des compilers lesen soll, oder nicht?
Ist das als Witz gemeint? Falls nicht: Geh bei undefiniertem Verhalten davon aus, dass theoretisch dein Programm die Welt explodieren lässt. Es ist undefiniert, es kann alles passieren. Der Compiler definiert da nichts, er nimmt schlicht keine Rücksicht. Sonst wäre es Implementations spezifisches Verhalten.
-
und ihr könnt da keinen "designfehler" oder so entdecken?
-
@Wade1234
Youtube: Chandler Carruth über Undefined Behaviour
-
@Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
und ihr könnt da keinen "designfehler" oder so entdecken?
Nein. Wenn du's kuschelig warm und immer (*) definiert haben willst, dann musst du ne "managed" Sprache ala Java oder C# verwenden. Wenn dich das jetzt überrascht, dann könnte vielleicht ein Bisschen Backgroundwissen nicht schaden. Also darüber wie Computer allgemein so funktionieren (CPU, RAM, Registert), wie Speicherverwaltung typischerweise gemacht wird und wie das so mit den Zeigern ist.
*: Naja, ne, leider doch nicht immer. Aber eher/öfter als bei C++.
-
naja also ich weiß, dass ich ungültige zeiger auf NULL setzen soll, damit das programm, wenn ich diesen zeiger fehlerhafterweise verwende, gesichert abstürzt und nicht mit falschen werten weiter läuft, und wahrscheinlich sollte man das mit dateideskriptoren auch so machen.
-
Habs auch mal (mit VS) getestet. fwrite() reagiert tatsächlich allergisch auf einen geschlossenen FILE*.
Aber mit einen kleinen Trick lässt sich das umgehen:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> int main() { FILE *f1 = fopen("c:\\f1", "w"); FILE *f2 = fopen("c:\\f2", "w"); printf("%d\n", _fileno(f1)); // positive zahl printf("%d\n", _fileno(f2)); // " " _fcloseall(); printf("%d\n", _fileno(f1)); // -1 printf("%d\n", _fileno(f2)); // dito }
Also vor dem Zugriff immer mit _fileno() auf Gültigkeit des FILE* checken, dann klappt's auch mit _fcloseall().
Btw, Nach einem gezielten fclose() spuckt _fileno() auch -1 aus.
-
@RBS2 Hmmmm
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fileno?view=vs-2017
The result is undefined if stream does not specify an open file.
-
@Dravere sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
@RBS2 Hmmmm
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fileno?view=vs-2017
The result is undefined if stream does not specify an open file.
Da wollte MS wohl wieder etwas anders machen.
Upon successful completion, fileno() shall return the integer value of the file descriptor associated with stream. Otherwise, the value -1 shall be returned and errno set to indicate the error.
http://pubs.opengroup.org/onlinepubs/009696899/functions/fileno.html
-
@RBS2
Ich finde das inzwischen bewundernswert, mit welcher Ignoranz und Hartnäckigkeit du deinen Standpunkt verteidigst. Hat irgendwie so´n Flachweltler-Charme. Witzig anzuhören, aber nicht ernst zu nehmen.
-
@DocShoe sagte in Verhalten von fcloseall und dessen Einsatzgebiet:
Hat irgendwie so´n Flachweltler-Charme.
Dass die Erde eine Scheibe ist, weiß doch inzwischen jeder auf dem gesamten Globus.