Hallo, welches Busch oder welche andere Quelle würdet ihr empfehlen für die Frage was man alles beachten muss wenn man weit verbreitete C++ Library Funktionen benutzt. Z.B. wenn man Dateien öffnet und benutzt. Was ich konkret hänge ist die Frage, wenn man eine Datei öffnet und einen File Pointer bekommt der nicht der NULL Pointer ist, ist dann alles ok oder muss man dann doch noch den Statuswert testen? Und was muss man sonst noch beachten an exotischen Sonderfällen die auftreten könnten? (Datei liegt auf einem Samba Share der ein ext3 oder NTFS Dateisystem hat, dessen Rechte plötzlich..., und das Netzwerk hängt ein wenig, kommt aber wieder, oder was anders extotisches. Das da Tipps gibt wie: Wenn man einen File Handler bekommt, muss man doch noch dieses und jenes beachten weil meist geht es gut aber es könnte doch sein dass...) Einfach ein Kompendium über die Sachen die man beim professionellen Programmieren beachten muss, die nicht Teil der Grundlagen-Vorlesung waren. Die bei einfachen Situationen egal sind, aber wenn man alle Spezialfälle abdecken will braucht man mehr Hintergrund-Infos. Gerne auch speziell zu Windows 7-10 und Visual C++. Ich meine jetzt nicht so abstrakte Sachen wie "continuous integration" oder "clean code" sondern konkret Fragen wie: Was muss man beachten wenn man die lib-Funktionen benutzt und welche Methoden oder libs haben welche Vor- und Nachteile (z.B. wenn es mehrere Methoden oder libs gibt mit denen man auf Dateien zugreifen kann, um bei dem Beispiel zu bleiben). Für ein altes Unix mit C hatte ich mal so ein Buch, aber was gibt es für Windows 7-10 und Visual C++?
asd schrieb: > aber was gibt es für Windows 7-10 und Visual C++ Ich hab kein konkretes Buch, weil ich mir immer die Dokumentation durchlese. Prinzipiell kann man sich dann nur auf das verlassen, was in der Dokumentation garantiert wird. Der Rest kann funktionieren oder auch nicht, also keine Annahmen einfach so oder durch ausprobieren treffen. Bei deiner Frage musst du aber noch zwischen Bibliothek und Betriebssystem unterscheiden. Bei z.B. C++, boost oder Qt sollte es bis auf die Pfadsyntax unabhängig vom Betriebssystem sein. Wenn du jetzt Win32 direkt verwendest, dann gilt das was Windows dort vorgibt. Gerade in den Details, die für dich ja relevant sind, unterscheiden sich die verschiedenen Libs aber durchaus. Deshalb wirst du wahrscheinlich kein allgemeines Kompendium finden, wenn du dich nicht auf eine Bibliothek einschränkst.
> Prinzipiell kann man sich dann nur auf das verlassen, was in > der Dokumentation garantiert wird. Das ist klar. Diese Beschreibungen sind mir aber oft zu abstrakt, bzw. ohne die nötige "Griffigkeit" in der Praxisrelevanz. Z.B. kam die Frage auf, wenn fopen einen nicht-NULL-Pointer als File Handler zurück liefert, ist dann alles ok? Oder gibt es doch Spezialfälle in denen man noch weiteres beachten muss? Z.B. könnte was in der Zeit passieren zwischen dem Aufruf von fopen und fclose. Zugriffsrechte werden verändert, das Netzwerk zum Samba-Share hat einen hänger, was auch immer. Vielleicht ist das egal, fclose fängt da ab. Vielleicht gibt es einen Spezialfall in dem man als Programmierer beachten. Die reine Beschreibung der lib gibt das nicht her (zumindest nicht so dass ich mir sicher bin dass ich es verstanden habe) Kann man einfach fclose aufrufen wenn man einen nicht-NULL-Pointer von fopen bekommen hat (Konkretes Problem: In ganz seltenen Fällen crasht das Programm beim fclose, und keiner weiß warum. Theorie: Die Fehler-Abfang-Logik beachtet einen Sonderfall nicht) Außerdem können beim Kunden exotische Konfigurationen auftreten die keiner vorhersehen kann. Da wäre ein Kompendium nicht schlecht das einen durch einen konkreten Fall führt und z.B. ein Kapitel darüber hat was die Best Practises sind beim Files auf- und zu machen. Und zwar nicht nur den einfachen Fall, sondern auch für die praxisrelevanten Sonderfälle. Klar, dazu braucht es einen Autor der Ahnung hat, und davon gibt es nicht viele. Natürlich kann so ein Buch nicht alle libs abdecken, aber wenn die üblichen libs abgedeckt werden sind die bei Visual C++ dabei sind, wäre das ein Anfang. Und vielleicht wird man in dem Buch ja auf andere Methoden und libs hingewiesen die für manche Anwendungen besser sind.
asd schrieb: > fopen einen nicht-NULL-Pointer als File Handler zurück liefert, Das ist kein "Handler", sondern ein "Handle". Ein "Handler" ist eine Funktion o.ä., die etwas behandelt, ein "Handle" ist ein "Griff", ein Ding, womit man etwas "anfassen" oder "manipulieren" kann, wie eben Deine Datei. Wenn Du davon ausgehst, daß die Netzwerkverbindung sehr instabil ist, dann musst Du vor jeder Dateioperation die Gültigkeit der hinter dem Handle steckenden Verwaltungsinformationen prüfen. Die Funktionen der Standardlibrary gehen nicht von derartig kaputten Umgebungen aus, Du wirst also mit den unterliegenden Betriebssystemfunktionen hantieren müssen, wenn Du jeweils den tatsächlichen Status der Dateiverwaltungsinformation prüfen willst. Da da aber einiges an Caching dazwischen liegen dürfte, wird das noch nicht mal besonders einfach. In so einer Situation ist es am sinnvollsten, die Datei nur solange jeweils geöffnet zu haben, wie tatsächlich auf Inhalte zugegriffen wird, und sie sofort danach wieder zu schließen.
Rufus Τ. F. schrieb: > Wenn Du davon ausgehst, daß die Netzwerkverbindung sehr instabil ist, > dann musst Du vor jeder Dateioperation die Gültigkeit der hinter dem > Handle steckenden Verwaltungsinformationen prüfen. Da die Probleme aber auch auftreten könnenen direkt nachdem man geprüft hat und bevor oder während man den Handle nutzt ist das nicht wirklich machbar. Das einzige was man machen kann ist "normale" Fehlerbehandlung zu nutzen, also Rückgabewerte von fopen/fread/ferror und wenn nötig errno auslesen. asd schrieb: > (Konkretes Problem: In ganz seltenen Fällen crasht > das Programm beim fclose, und keiner weiß warum. Theorie: Die > Fehler-Abfang-Logik beachtet einen Sonderfall nicht) Dann solltet ihr die Doku nochmal lesen und sicher stellen, dass eure Fehler-Abfang-Logik korrekt ist.
Ein Handle ist eine dynamische Zugriffsnummer auf eine Systemresource und kann vom System wieder verwendet werden. Solange das Handle als invalid markiert ist bekommst du beim close INVALID_HANDLE zurück. Wenn das System das Handle jedoch schon recycled hat kann es wieder gültig sein und du schliesst ein anderes Systemobjekt. Vermutung: Irgend jemand schliesst dein Handle und du greifst nach einer gewissen Zeit darauf zu.
lemma 1: Niemand kann von haus aus nach Schema-F den absolut richitgen Code schreiben. lemma 2: Jeder Code, der nicht getestet ist, funktioniert nicht. lemma 3: lerning by doing is a must. Reines Programmieren perfekt lernen zu wollen ist wie Chinesisch zu lernen, ohne es je anzuwenden. Daraus folgt: Du wirst nie Chinesisch können. Du kannst auch Kochen nicht über Rezepte lernen. In 21 Tagen zum 5-Sterne-Koch: Vergiss es! Die Lösung deines Anspruches in Sachen Perfektion liegt in Deinem iterierenden Bemühen, also Deinem Fleiß und Deine Ausdauer, Problemstellungen erkennen, analysieren, erfassen und lösen zu können. Danach die Lösung zu Perfektionieren, meint in puncto Tests, Sicherheit, continous integration etc., alles das, was Du jetzt eben nicht "sexy" findest. Aber das gehört unbedingt dazu. Perfektes Programmieren lernen zu wollen, ohne den Bezug zu Software Engineering haben zu wollen ist: infantil. Backgroundinformation: 1. Geh in eine (Uni)Bibliothek. Verbring viel Zeit dort. Du wirst es nie wieder missen wollen. a. Such Dir verschiendeste Literatur von Bjarne Stroustrup z.B. zum Thema "The C++ Programming Language" und anderes mehr von ihm. b. Such Dir zum Thema Secure Programming for C and C++ Literatur, studier sie begleitend zu Übungen und Kommunikation mit anderen (Foren, Listen etc.) c. Such Dir Literatur zu C und Richard Stallman, studier sie. Versuche selbst den Unterschied herauszufinden zwischen Visual C++ und C++ und C. d. Such Dir Bücher über Praktische C++ Programmierung. Siehe O'Reilly Serien etc. e. Such Dir Bücher über Effective C++ z.b. von Scott Meyers. f. Such Dir Primers über C++ und versuche die darin enthaltenen Beispiele zu programmieren. g. Such Dir Bücher generell über Software Engineering, damit Du Aufgabenstellungen überhaupt einmal erst richtig "behirnen" lernst. h. Such Dir eine andere Programmiersprache aus z.B. LISP . Versuche die Übungen, die Du mittels C++ geschafft hast mit LISP zu lösen. i. Verschaff Dir generell mal einen Überblick über die Art und Vielzahl von Programmiersprachen. j. Lerne eine neue, weitere Programmiersprache. k. Suche Dir Literatur über Noam Chomsky ... Generative Grammatik Solltest Du nach dem Punkt K nicht von selbst die Punke L-Z finden, kannst Du Dich gerne an mich wenden, um sie Dir aufzulisten. Ich denke aber, wenn Du bis K gekommen bist, erübrigt es sich. Dann bist Du auf solidem Weg in deinen Beruf (=kommt von berufen sein). Den seinen gibts der Herr im Schlafe. Angeblich. Doch das trifft, wenn überhaupt nur auf die Wenigsten zu. Im Schweisse deines Angesichts sollst Du Dir Dein Brot verdienen. Gruß Ein Freund
Allgemeines wird da nie alles abdecken, egal wie lange man in der Biblio. rumhängt oder Bücher wälzt(wobei das aber generell nicht verkehrt ist:-) Ansatzpunkt würde ganz konkret bei den jeweiligen Funktionen nach zuschauen. z.B.: http://www.cplusplus.com/reference/fstream/fstream/open/ Da wird auch etliches zu den "Fehlerfällen" geschrieben. Und dazu noch die zugehörige ähnliche Beschreibung der konkret verwendete Funktion des verwendeten Compilers (inkl. der mitgelieferten Std.Bibliothek)...
Es mag individuell unterschiedlich sein, aber für mich gilt: Programmieren lernt man nicht aus Büchern. Man kann (und sollte) die Grundlagen des Programmierens aus Büchern lernen, aber richtig Programmieren lernt man nur durch eines: Praxis. Anstatt also in Bibliotheken rumzuhocken, solltest Du dich vor eine Tastatur setzen und machen. Wenn Du das, was Du bis dahin weißt, wirklich beherrschst, greifst Du wieder zu einem Buch.
asd schrieb: > Das ist klar. Diese Beschreibungen sind mir aber oft zu abstrakt, bzw. > ohne die nötige "Griffigkeit" in der Praxisrelevanz. Das liegt daran, dass sie abstrakt genug sein müssen, um auch auf Anwendungsfälle anwendbar zu sein, die der Autor in diesem Momemtn nicht auf dem Schirm hatte. > Z.B. kam die Frage auf, wenn fopen einen nicht-NULL-Pointer als File > Handler zurück liefert, ist dann alles ok? In erster Linie ist dann zumindest nichts Offensichtliches falsch (d.h. die Datei existiert oder kann erzeugt werden, du hast ausreichende Rechte, usw.) > Oder gibt es doch Spezialfälle in denen man noch weiteres beachten > muss? Z.B. könnte was in der Zeit passieren zwischen dem Aufruf von > fopen und fclose. Unvorhergesehene Dinge können immer passieren. Im Extremfall schaltet jemand einen beteiligten Rechner aus. Ob deine Software damit umgehen können muss, hängt von deiner Anwendung ab. Dazu kommt noch, dass Caching real existiert. Selbst, wenn ein fwrite() gelingt, heißt das nicht, dass die Daten auch tatsächlich in der Datei gelandet sind. Erst, wenn auch das fclose() erfolgreich ist, kannst du davon ausgehen, dass alles erledigt wurde. Daher der Ratschlag, die Datei nur möglichst kurz offen zu halten, wenn die Netzwerkverbindung nicht sauber ist. Schnell ist anders, aber "sicher, schnell, billig" geht halt nicht alles. > Zugriffsrechte werden verändert, das Netzwerk zum Samba-Share hat einen > hänger, was auch immer. Bei Netzwerkdateisystemen hängt es vom Dateisystem ab, welche normalerweise existierende Garantien nicht mehr gelten. Es kann gut sein, dass eine Datei während des Zugriffs für andere Nutzer gesperrt ist (Locking), aber es muss nicht so sein. Hängt auch davon ab, was deine Anwendung vorher angefragt hat. Es gibt Windows-APIs für File-Locking, Record-based locking und so Zeugs. > Kann man einfach fclose aufrufen wenn man einen nicht-NULL-Pointer von > fopen bekommen hat (Konkretes Problem: In ganz seltenen Fällen crasht > das Programm beim fclose, und keiner weiß warum. Theorie: Die > Fehler-Abfang-Logik beachtet einen Sonderfall nicht) Wenn du ein gültiges Handle von fopen() bekommen hast, dann kannst du es an fclose() übergeben. Genaueres gibt es nur, wenn du uns über den Crash informierst. In deinem Fall geht es nicht um irgendwelche speziellen Libs, sondern um die C-Standardbibliothek. Die ist nicht gerade unbekannt.
S. R. schrieb: > Erst, wenn auch das fclose() erfolgreich ist, kannst du > davon ausgehen, dass alles erledigt wurde. Selbst dann nicht. Ob das OS und die Hardware ihre eventuell vorhandenen Writecaches dann schon weggeschrieben haben ist an der Stelle alles andere als sicher. S. R. schrieb: > Wenn du ein gültiges Handle von fopen() bekommen hast, dann kannst du es > an fclose() übergeben. Man kann nicht nur, man sollte sogar.
Frank _. schrieb: > Selbst dann nicht. Ob das OS und die Hardware ihre eventuell vorhandenen > Writecaches dann schon weggeschrieben haben ist an der Stelle alles > andere als sicher. Stimmt, ein fclose() garantiert nur ein fflush(), aber kein fsync(). Hätte ich jetzt ehrlich gesagt nicht erwartet. Also vorher unbedingt noch ein fsync() nachschieben, wenn die Daten garantiert lesbar sein müssen - bessere Garantien gibt dann aber tatsächlich nicht mehr. Frank _. schrieb: >> Wenn du ein gültiges Handle von fopen() bekommen hast, >> dann kannst du es an fclose() übergeben. > > Man kann nicht nur, man sollte sogar. Man kann auch ein anderes Handle an fclose() übergeben oder das Betriebssystem das beim Programmende erledigen lassen. ;-) Aber natürlich hast du recht. Ich meinte nur, dass ein von fopen() übergebenes Handle niemals von selbst ungültig wird, also immer an fclose() übergeben werden kann.
S. R. schrieb: > Stimmt, ein fclose() garantiert nur ein fflush(), aber kein fsync(). > Hätte ich jetzt ehrlich gesagt nicht erwartet. > > Also vorher unbedingt noch ein fsync() nachschieben, wenn die Daten > garantiert lesbar sein müssen - bessere Garantien gibt dann aber > tatsächlich nicht mehr. Das halte ich nur sehr bedingt für einen guten Rat. Auf "normalen" Betriebssystemen darf man davon ausgehen, daß ein fclose() die Daten auch irgendwann mal zuverlässig auf die Platte bringt. Wenn jetzt alle glauben, ihre Programme seien wichtiger als andere, anfangen, ihren Disk-Caches zu mißtrauen und fsync()en, können die Betriebssystemhersteller die Caches auch gleich weglassen. Im Übrigen garantiert ein fsync() auf den Filedeskriptor einer offenen Datei lediglich, daß die Datei-Daten auf der Platte gelandet sind. Für den entsprechenden Directory-Eintrag gilt das nicht. Es kann also immer noch passieren, daß zwar die Daten da sind wo sie hingehören, aber der Verzeichniseintrag eben nicht (und die Datei damit auch kaputt ist). Wenn man's ganz wasserdicht haben will, muß man (mit einem entsprechenden Descriptor) das Verzeichnis ebenso fsyncen.
asd schrieb: > Konkretes Problem: In ganz seltenen Fällen crasht > das Programm beim fclose, und keiner weiß warum. Hierbei dürfte es sich ziemlich sicher schlicht um einen (Programmier-) Fehler beim Umgang mit dynamisch allokiertem Speicher bzw. einen einfachen "Überschreiber" handeln. fclose() ruft intern (u.a.) fflush() und free() auf. Wenn Ihr's irgendwie geschafft habt (z.B. durch ein free() von Speicher, der nicht dynamisch allokiert wurde oder durch Überschreiben von Speicher, der Euch nicht gehört) diese Pufferaddressen zu verbiegen, kann es zu solchen sporadischen Abstürzen kommen. Ich würde mich an deiner Stelle mit valgrind (oder einem anderen Programm, das solche Fehler aufdecken kann) daran machen, Euer Programm kritisch zu untersuchen.
S. R. schrieb: > Dazu kommt noch, dass Caching real existiert. Selbst, wenn ein fwrite() > gelingt, heißt das nicht, dass die Daten auch tatsächlich in der Datei > gelandet sind. Erst, wenn auch das fclose() erfolgreich ist, kannst du > davon ausgehen, dass alles erledigt wurde. Gerade das ist bei fclose NICHT der Fall. Nur was in der C-Lib u.U. noch gebuffert ist, sollte dann dem OS übergeben worden sein. Was das OS/die Treiber/die Hardware dann noch machen ist eine andere Geschichte (unter Linux reicht sync/fsync u.U. nicht 1)) 1) bspw. btrfs "Btrfs does not force all dirty data to disk on every fsync or O_SYNC operation, fsync is designed to be fast." https://btrfs.wiki.kernel.org/index.php/FAQ#Does_Btrfs_have_data.3Dordered_mode_like_Ext3.3F
Arc N. schrieb: > Gerade das ist bei fclose NICHT der Fall. Das wurde mir bereits mitgeteilt und ich habe meine Aussage diesbezüglich bereits revidiert. Drei Posts über deinem. Lesen!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.