Frage von leoquestiongoon, 163

C++ Kommazahlendivision geht nicht?

include

using namespace std;

int main () { long double n; cin >> n; long double m; cin >> m; cout << m/n; return 0; }

Ich bekomme bei der Division aber nur Zahlen mit nicht mehr als 4 Kommastellen angezeigt. so geht mein Quellcode. Ich benutze den dev Compiler. statt m/n habe ich auch schon m:n probiert. Woran kann es noch liegen.

Expertenantwort
von TeeTier, Community-Experte für programmieren, 69

Bitte beachte die Antwort von "saraj" nicht weiter, da diese sowohl dich und auch andere mitlesende Anfänger verwirren wird, und du dir damit einen sehr sehr schlechten Programmierstil angewöhnst. Die Argumente in der Diskussion von DontHaveAName sind absolut korrekt und das, was man von einem erfahrenen Programmierer erwarten dürfte.

Zu deiner eigentlichen Frage: Guck dir doch bitte erst mal die Dokumentation des Output-Streams an ...

http://www.cplusplus.com/reference/ostream/ostream/?kw=ostream

Besonders der Link zu "precision" dürfte für dich interessant sein:

http://www.cplusplus.com/reference/ios/ios\_base/precision/

In dem Code-Beispiel der Seite sollte alles stehen, was für dein Problem relevant ist.

Viel Spaß mit C++! Und ohne jetzt weiter auf Details eingehen zu wollen, merke dir einfach Folgendes: Ein kompetenter Programmierer vermischt C und C++ niemals, wenn es nicht einen verdammt guten Grund dafür gibt! Anfänger bis Fortgeschrittene sollten grundsätzlich darauf verzichten. Der Hauptgrund ist die hohe Fehleranfälligkeit, die durch mangelnde Typprüfung bei reinem C-Code entsteht, und viele viele subtile Inkompatibilitäten zwischen C und C++, die in der Vergangenheit schon oft Grund für schwere Sicherheitslücken waren.

PS: Noch ein paar Worte zu mir persönlich ... Ich programmiere seit 1990 in C bzw. C++ und suche beruflich nach Sicherheitslücken in Soft und Hardware. Und die allermeisten schweren Bugs entstehen durch Leute, die selbst nicht merken, wie schlecht sie eigentlich programmieren. Es sind seit fast 30 Jahren immer und immer wieder die selben Fehler, die von Menschen gemacht werden, welche am Anfang ihrer Karriere denken, sie wüssten alles.

Und DIE klassischste aller klassischen Sicherheitslücken überhaupt ist ein Pufferüberlauf, verursacht durch Formatstrings in printf(), also genau das, was "saraj" dir empfohlen hat. Mit den Output-Streams von C++ sind solche Fehler nun nicht mehr möglich. Also höre auf jeden Fall auf das, was "DontHaveAName" geschrieben hat, und gewöhne dir um Gottes Willen nicht die Benutzung von printf() an!

Kommentar von sarahj ,

möchte nochmal, ohne die Diskussion nochmal anheizen zu wollen ein paar DInge klarstellen, die man hier nicht so stehen lassen kann.

1) ich habe unten selbst geschrieben, daß ich prinzipiell (wörtl. "im Allgemeinen") eurer Meinung bin.

2) ich lediglich gegen dogmatisches Befolgen von Regeln bin, insbesondere, wenn auch innerhalb der Community durchaus Uneinigkeit  herrscht.

3) (und dazu stehe ich immer noch) man sich im Einzelfall auch mal einen C Aufruf (insbes. stdio) entscheiden kann, wenn dies angebracht erscheint.

4) man sich in diesem Fall (printf) möglicherweise darüber streiten kann, ob er angebracht ist, oder nicht.
Und wer stackoverflow und andere Foren liest, findet auch dort ähnlich emotional geführte Streits. Ganz so als Außenseiter möchte ich also nicht stehen bleiben

5) eure anderen Argumente durchaus richtig sind, aber in diesem Fall nicht wirklich passen. Mit sizeof und calling conventions hat diese Diskussion nichts zu tun. Ein Bufferoverflow bei printf geht mit %n als Format. Anders sieht die Sache bei sprintf und natürlich scanf etc. aus. Aber darum ging es hier nicht.

6) hättet ihr nicht das "threadsafe" Argument nicht gebracht, wäre ich darauf nicht weiter eingegangen. Aber ich wurde genau damit als unwissender Anfänger hingestellt.
Ein Argument gegen setprecision ist aber: es setzt einen State im stream. Wenn also in einem großen Projekt (mit mehreren Programmieren und verteilter Entwicklung) irgend einer mal ein bestimmtes Format braucht, ist es danach auch für den nächsten umgesetzt. Es hat also nicht-lokale Auswirkungen. Es wird also jeder die precision wieder vor jeder Nutzung umsetzen müssen. Und bei mehreren threads kriegen wir damit genau das "threadunsafe" Problem, von dem ihr geschrieben habt.
Dieses hat man bei printf nicht. So ging mein Argument: abwägen.

7) der offizielle C++ Standard erwähnt explizit, daß stdio Teil auch des C++ Standards ist. Und es ging hier, wie gesagt, um printf, nicht um das allgemeine Mischen von C/C++.

8) Die persönlichen Kompetenzattacken sind völlig daneben, und ich entschuldige mich für den "Jungprogrammierer". Allerdings möchte ich dazufügen, dass ich mich dazu durch "Oh weia..." habe hinreissen lassen, was dumm war. Aber die Eskalation war dann doch etwas unwürdig.

Eigentlich finde ich solcherlei kindisch, und ich habe keine Lust, auf Kindergartenniveau "wer hat den größeren" mit euch zu spielen.
Aber nur soviel: auch ich habe schon einiges im Leben gesehen, und ein paar Zeilen Code geschrieben.
Vielleicht telefoniert ihr sogar gerade damit, überträgt damit Texte oder Geldbeträge. Oder der Strom aus eurer Steckdose wird damit gesteuert oder der Stahl eures Autos damit gepresst. Ein paar meiner alten Codezeilen laufen vielleicht auch in eurer eigenen Mühle, falls ihr kein Windows verwendet.
Und ob meine Ansichten so schlecht sind, werde ich demnächst mal meine Informatik Studenten fragen. Die waren aber bisher durchaus zufrieden (könnte aber im nächsten Kurs geneigt sein mal nachzufragen, ob da ein donthave dabei ist...).
Ein paar wenige Jahre Erfahrung habe ich auch - tatsächlich war ich 1990 schon 'ne Weile im Geschäft. Und habe Code von größeren Programmierteams zusammenbringen, debuggen und derlei Fehler finden müssen.

9) daß C++ freaks eigene Ansichten haben, wusste ich schon länger. Daß sie aber so dermassen unter der Gürtelliene agieren schockiert mich ein bisschen. Daher war's das dann auch in diesem thread. Schönen Abend noch.

Kommentar von TeeTier ,

Dir kommt es so sehr auf den Streamstate an, aber dir ist schon klar, dass ...

printf("%.3f", x);

... NUR bei C keinen State besitzt, bei C++ hingegen schon, oder?

(Die Auwirkungen davon merkt man allerdings nicht bei "Hello World", sondern leider erst dann, wenn man seinen Code in eine Library verpackt oder mit Modulen Dritter interagiert ... und dann ist es meistens schon zu spät. Und das Tollste: Sogar völlig ohne Nebenläufigkeit)

Und im Gegensatz zur Möglichkeit, den State VOR precicion() und Konsorten zu retten, und dieses auch nach getaner Arbeit wiederherstellen, hat man bei obigem printf() Beispiel unter C++ überhaupt nicht mal die Chance den State zu schützen, ohne etwas kaputt zu machen ... versucht man es dennoch: Implementation Defined Behavior, oftmals in Datenmüll resultierend.

Wie gesagt, dieses Problem existiert bei reinem C nicht, und deshalb kennen reine Cler das auch nicht. Aber es wundert mich sehr, dass du mit deiner Erfahrung über den State unter C++ herziehst, den State unter C++ bei stdio-Streams hingegen außen vor lässt.

Und das meine ich: Viele Leute kennen die feinen Unterschiede zwischen C und C++ nicht. Kann man auch oft nicht. Und nicht mal ich traue mir das zu, da ich nicht Hellsehen kann.

Und GENAU aus diesem Grunde sollte man ein Mischen vermeiden. Wie DontHaveAName schon gesagt hat: Die beiden einfach als unterschiedliche Sprachen behandeln! Damit vermeidet man von vornherein etwaige Unstimmigkeiten.

Allerdings bin ich mit dir einer Meinung, dass C++ so einige Design-Schwächen hat. Leider nicht nur bei den Streams.

PS: Ich habe "Threads" bisher nirgendwo erwähnt. Das war jemand anderes. :)

Kommentar von procoder42 ,

Was hier noch gar nicht zur Sprache kam :

char text[1024]; printf(text);

Toller Code, nicht ?

Noch eine letzte Bemerkung zum Schw*nzvergleich, weil es gerade so schön ist ... :)

Ach komm, das hast du doch nicht nötig ...

Kommentar von TeeTier ,

Ach komm, das hast du doch nicht nötig ...

Du hast ja Recht ... ich lasse mich oft viel zu leicht provozieren. ><

Kommentar von procoder42 ,

werde ich demnächst mal meine Informatik Studenten fragen

So, so Vorlesungen .... Wo hältst du die denn ???

oder wenn du sündhaft teure Audio-Hardware in deinem Tonstudio eingesetzt hast

Ach so, dann schreibst du also diese Audio Interface Treiber, die trotz riesiger Dateigröße eine ewig lange Latenz haben (ca. 1 Sekunde) :D ....

Ich bin leicht gekränkt, dass bis jetzt kein Kommentar zu der von mir aufgezeigten Sicherheitslücke kam :( ....

Kommentar von TeeTier ,

Ich weiß, dass man hier - wegen besagter Baumdarstellung - leicht die Übersicht verliert, aber an wen genau richtet sich dein Kommentar jetzt eigentlich? :)

Der Teil mit den Informatik-Studenten kam nicht von mir. Aber ich gebe manchmal auf freiwilliger Basis Nachhilfe und korrigiere Abschlussarbeiten. ><

Und zu dem Teil mit den Audio-Interface-Treibern: Gibt es tatsächlich ein Gerät, was eine Latenz von einer ganzen Sekunde hat? Wie soll man damit noch arbeiten können? Ich bezog mich eigentlich mehr auf Synthesizer, allen voran von Roland. :)

Zu deiner Sicherheitslücke: Speicherinitialisierung wird überbewertet. Das machen eh nur Weicheier, die sich vor Segfaults fürchten. :)

Zu Brotsorten: In Deutschland gibt es weltweit die meisten Brotsorten. Weit über 1000! ... hat jetzt zwar überhaupt nichts mit dem Thema zu tun, habe ich aber gerade gelesen und verspüre jetzt den Zwang, dieses Wissen hier weiter zu verbreiten.

Schönen Tag noch! :)

Kommentar von procoder42 ,

Ich weiß, dass man hier - wegen besagter Baumdarstellung - leicht
die Übersicht verliert, aber an wen genau richtet sich dein Kommentar
jetzt eigentlich? :)

Leider kann man hier keine Nutzer direkt addressieren. Der eine Teil bezog sich auf dich, andere nicht.

und korrigiere Abschlussarbeiten. ><

Ich leide mit dir. Was ich teilweise bei Klassenkameraden für Code lesen muss ...

Gibt es tatsächlich ein Gerät, was eine Latenz von einer ganzen Sekunde hat? Wie soll man damit noch arbeiten können?

In der Tat. War bei einem Universal Audio Interface der Fall ...

Kommentar von TeeTier ,

Noch eine letzte Bemerkung zum Schw*nzvergleich, weil es gerade so schön ist ... :)

Wenn du im Mobilsektor allen voran Android, iOS, oder Uralt-Symbian benutzt, wenn du auf dem Desktop ein Apple-System, ein Linux, ein BSD oder Windows einsetzt, wenn du irgendeinen Server einsetzt, der gängige Kompressionen unterstützt, wenn du in den letzten 20 Jahren ein Computerspiel gespielt, ein Auto gekauft oder Geld bei deiner Bank abgehoben hast, wenn du mit einem Flugzeug geflogen oder MIDI-Controller eingesetzt, oder wenn du sündhaft teure Audio-Hardware in deinem Tonstudio eingesetzt hast, und wenn du zum Arzt gehst und dabei ein Röntgen, Ultraschall oder MRT zum Einsatz kommt, genau dann wirst du mit allerhöchster Wahrscheinlicheit indirekt mit meinem Code in Berührung kommen.

Ich würde sogar wetten, dass es seit spätestens 10 Jahren in ganz Europa keinen einzigen Menschen mehr gibt, der noch nichts mit Geräten zu tun hatte, die Code von mir enthalten. Vom Säuglling noch vor der Geburt, bis zum kürzlich Verstorbenen. Höchstens vielleicht Obdachlose, Einsiedler oder Technikverweigerer, die in der Pampa leben, könnten dabei durchs Sieb fallen, aber nur wenn sie seit Mitte der 90er durchweg im Wald leben, und keinerlei Kontakt zur Außenwelt haben. Die Anzahl der Leute, die einen Facebook- oder Twitter-Account haben, dürfte weit darunter liegen.

OK, genug davon ... schönen Abend noch! :)

Antwort
von fairytale48, 40

Höre auf TeeTier undDontHaveAName! Schön wäre auch, wenn du dir gleich using namespace std; abgewöhnst. Falls nicht, wirst du später merken, warum. Ansonsten hier noch mal für die, die nicht TeeTiers Link folgen wollen, <iomanip>, std::fixed, std::setw(int w) und std::setprecision(int p) lösen das Problem. Hau rein!

Kommentar von TeeTier ,

Genau, std:: sollte man immer einsetzen, oder den Namespace zumindest Funktions- oder Blocklokal über eine using-Direktive einführen.

Ich lasse das aber trotzdem meistens in Beispielcode weg, da ich dessen Verwendung halb-unterbewusst sowieso immer voraussetze. :)

Antwort
von sarahj, 113

nimm mal printf, anstatt "<<" zur Ausgabe.
z.B.

main() {
   ...

   printf(stdout, "%F %F %F\n", m, n, (m/n) );

}

Da kannst Du die Anzahl Stellen angeben:

   printf(stdout, "%10.8F ...", ...);

und google nach "printf format string"

Kommentar von DontHaveAName ,

Es wird nach einer C++ Lösung gefragt und nicht nach einer C Alternativen.

Kommentar von sarahj ,

oha, ein Erbsenzähler.
C ist eine Untermenge von C++, Und Funktionen aufrufen ist da auch erlaubt.

Kommentar von DontHaveAName ,

Oh weia. Dann bist du also eine Person die gerne C Funktionen mit denen von C++ vermischt ja? Dann kann ich mir deinen Quellcode schon gut vorstellen. Nein Danke...

Kommentar von sarahj ,

na wenn Du meinst...

Kommentar von DontHaveAName ,

Tut mir ja leid, aber es ist ein Fakt das es ein schlechter Programmierstil ist, wenn man C Funktionen mit C++ Funktionen mischt.

Solange C++ einem die Möglichkeit gibt etwas zu machen, sollte man in keinem C++ Projekt auf eine C Funktion zurückgreifen.

Kommentar von sarahj ,

so, und warum? Aus Prinzip, weil es der Jungprogrammierer so in einer Vorlesung gehört hat, oder gibt es da außer "Fakt ist" auch ein logisch nachvollziehbares Argument?

Habe leider im Lauf meines Lebens einige getroffen die zwar sehr auf Prinzipien herumritten, aber praktisch wenig Lauffähiges zustande gebracht haben.

Das soll jetzt nicht heissen, daß ich Dich so einschätze, aber Prinzipien können leicht zu Dogmen werden...

Und im allgemeinen würde ich Dir wohl Recht geben, aber in diesem speziellen Fall geht es um ein ein Anfängerprogrämmchen, einen 1-Zeiler, das eine Zahl ausgeben soll. Nicht darum, später mal cout durch eine andere Instanz zu ersetzen und den Code möglichst flexibel und erweiterbar zu halten.
Man kann es auch übertreiben.

Kommentar von DontHaveAName ,

Erstens, ja, C Funktionen kompilieren **mehr oder weniger problemos** mit einem C++ Kompiler.

Trotzdem sollten diese beiden Sprachen letzendlich als komplett verschiedene Sprachen aufgefasst werden.
Und solange es keinen vernünftigen Grund gibt, sollte man diese eben nicht vermischen.

Ein Beispiel warum es schlecht ist? Ganz einfach, der C99 und C11 Standard hat beispielsweise Funktioalitäten, von denen C++
keine Ahnung hat.

C++ ist stark typisiert. Wenn man dann also mit C rumspielen will, müsste man einiges casten um den gewünschten Typ zu erhalten.
Dadurch kann auch mal ganz schnell funktionierender Code flöten gehen.

Noch ein Beispiel? Thread-Safety... Meines Wissens nach sind C Funktionen nicht Thread-Safe, einige C++ Funktionen hingegen schon.  Viel Spaß dabei C Funktionen in den Thread-Safe Funktionen von C++ aufzurufen.

Es gibt etliche Argumente die dagegen sprechen. Und es hat nichts damit zu tun das ich sowas in der Uni mal gehört habe oder ähnliches.
Sowas wird uns dort nämlich leider nicht gesagt. Man benötigt Eigenitiative um solche Dinge zu lernen.

Es macht hier auch keinen Unterschied ob es ein Einzeiler ist oder nicht. Er will C++ lernen, kein C.

Wenn du ihm jetzt schon zeigst, das man ja auch einfach mal auf C-Funktionen zurückgreifen kann, nur weil man gerade eben nicht weiß, wie man es vernünftig in C++ implementiert, wird sein künftiger Quellcode entsprechend aussehen. Ich will nicht derjenige sein, der sich dann damit rumschlagen muss.

Kommentar von sarahj ,

Gerade dein Beispiel zeigt, wohin unreflektiertes, dogmatisches Befolgen von Regeln ohne Sinn führen kann.

Dein Beispiel wird den Code gerade unsafe und weniger wartbar machen.

std::setprecision ist ein Paradebeispiel dafür, wie man eine Library schlecht macht. Leider haben auch die C++ Entwickler oft wenig Hirn in ihr Design reingesteckt.
Sowas bereits früh beizubringen führt später zu fast unwartbarem code. Ich bin mal froh, daß ich mich mit solchem code nicht (mehr) rumschlagen muss.
(ausgerechnet thread-safety hier als Argument anzubringen...)

PS: und wenn Du nicht siehst, wo setprecision ein Problem hat, solltest Du noch 1-2 Semester dranhängen.

Kommentar von DontHaveAName ,

Hättest du meinen Beitrag gelesen, wüsstest du das ich um Verbesserungen gebeten habe. Aber du scheinst es ja einfach zu ignorieren.

Außerdem habe ich dem Fragesteller nur einen Weg gezeigt, dies mit C++ zu lösen. Ich erwarte natürlich trotzdem von ihm, das er die entsprechende Funktion nachschlägt und genau schaut was diese tut.

Im Endeffekt geht es trotzdem darum, das man C und C++ einfach voneinander trennen sollte. Und ich bin mir ziemlich sicher, das ein so erfahrener Programmier-Guru wie du das auch weiß.

Wie dem auch sei. Schönen Abend noch.

Kommentar von TeeTier ,

Wow, ist ja nicht auszuhalten, so viel Unkenntnis!

Leider schießt du dir hier ein Eigentor nach dem anderen, und du zeigst allen Mitlesern, dass du die grundlegenden Programmierkonzepte weder von C++ noch von C verstanden hast.

Du befindest dich gerade in der ersten Phase des Dunning-Kruger-Effekts: die unbewusste Inkompetenz.

http://karrierebibel.de/dunning-kruger-effekt/

Du sprichst von Jungprogrammierer, bist aber eindeutig zu 100% selber einer. Aber sowas von ... und alle merken es. :)

Bevor du dich nächstes mal in die Nesseln setzt, solltest du dir für dieses UND nächstes Jahr vornehmen, etwas Fachliteratur zu lesen und dir bis zum Schluss jegliche Kommentare zu entsprechenden Themen verkneifen.

Aber denke bitte nicht, dass du nach Ende dieser Mini-Lernphase das Larvenstadium des "Jungprogrammierers" verlassen hast ... dazu gehört dann doch noch DEUTLICH mehr.

Ich gehe jetzt auf keinen einzigen Punkt deiner obigen Beiträge ein, da du so ziemlich alles falsch verstanden hast und falsch machst, was man falsch machen / verstehen kann, und ich hier nicht kostenlos deinen Dozenten spielen werde.

Für die nächsten 10 Jahre solltest du den Ball aber erst mal sehr sehr viel flacher halten. Dass sich jemand selbst öffentlich so dermaßen ins Knie schießt, wie du es hier getan hast, liest man wirklich nicht allzu häufig! :)

Und dass du die, die dich hier auf deine Fehler hinweisen anfährst, zeugt auch nicht gerade von Lernbereitschaft.

Nur so viel: Allein schon die von C und C++ eingesetzte ABI (besonders die Calling Conventions) haben sehr unterschiedliche Stärken und Schwächen. Es gibt sehr gute Gründe, in C++ auf printf() zu verzichten, und es sollte eigentlich nur für Legacy- oder reine C-APIs eingesetzt werden. Von mangelnder Typsicherheit mal ganz zu schweigen.

Im Übrigen ist C keine echte Teilmenge von C++. Viele C-Konstrukte sind in C++ unmöglich, bzw. verhalten sich völlig anders, und jeder der blindlinks C-Code in seinen C++ Programmen verwendet, wird früher oder später heftige Bugs provozieren.

Der Klassiker: Allein schon ...

sizeof('a')

... liefert in C und C++ völlig unterschiedliche Werte. Probiers aus, wenn du es nicht glaubst. :)

Naja egal ... Viel Spaß beim Lernen! Und verkneif dir doch einfach Kommentare zu Themen, in denen du nicht mal die Grundlagen verinnerlicht hast. Danke schön! :)

Kommentar von TeeTier ,

PS: Die Baumdarstellung der Kommentare ist hier bei GF so dermaßen verhunzt, dass ich nicht nachvollziehen kann, auf wessen Kommentar ich eigentlich geantwortet habe. Mein obiger Text richtet sich aber ausschließlich an "saraj"!

Die Argumente von DontHaveAName sind ausnahmslos nachvollziehbar und korrekt.

Ich kann Mitlesern, die noch Einsteiger, sind nur dringend empfehlen, nicht auf "saraj" zu hören. DontHaveAName hat offensichtlich DEUTLICH mehr Erfahrung!

Alleine schon an ...

Trotzdem sollten diese beiden Sprachen letzendlich als komplett verschiedene Sprachen aufgefasst werden.

... erkennt man, dass DontHaveAName hier einiges mehr verstanden hat als saraj. :)

Nicht dass sich hier der falsche angesprochen fühlt! ;)

Kommentar von DontHaveAName ,

Puh, gut zu wissen das ich auf dem richtigen Weg mit meiner Lernerei bin.

Schönen Abend noch :-).

Kommentar von sarahj ,

wow, jetzt wird aber geschossen.

Es geht hier um eine einfache Ausgabe eine Zahl!

Und es ist falsch, die precision als Zustand in einem Stream zu halten. Sorry. Spätestens wenn er den Code als Funktion oder in mehreren threads wiederverwenden will, kriegt er Probleme.

Daß c++ das so vorsieht, damit muss man leben. Und eine Verbesserung im Sinne von C++ kenne ich nicht.

Aber printf ist stateless. Keine Seiteneffekte.
Wer Dogmen wie "C++ muss rein bleiben" auf Kosten von Seiteneffekten fordert, mag zwar reineren C++ Code schreiben, wartbarer und fehlerfreier wird der Code damit aber nicht.

Also auch wenn C++ Fans offensichtlich leicht ungehalten werden: setprecision ist keine schöne Lösung. Und es als "höchste Kunst" zu verkaufen und mit threadsafety zu argumentieren ebenfalls nicht.

Und wenn Du Dich am Jungprogrammierer störst: mit ad-hominem Attacken hat dontHave angefangen. Ich kenne viele C++ Großprojekte, die genau an solchen Seiteneffekten scheiterten.
(und da hat es an Dogmatikern, Coding-Guidelines und C++-Konformität keineswegs gemangelt)

Aber eigentlich wäre mir eine Deeskalation recht.
Vielleicht können wir etwas ruhiger argumentieren?

Kommentar von TeeTier ,

Ob es falsch oder richtig ist, einen State in einem Stream zu speichern, ist jetzt erst mal nebensächlich. Das ist zwar nicht schick, aber so ist C++ nun mal. Ich denke, da sind wir uns einig. :)

Aber printf ist stateless. Keine Seiteneffekte.

Und genau hier sitzt der Hase im Pfeffer. Unter reinem C trifft deine Aussage evtl. zu (genau genommen auch nicht mal dort), unter C++ hingegen definitiv nicht mehr. Siehe dazu den Kommentar unter meiner Antwort.

Aber printf ist stateless. Keine Seiteneffekte. Wer Dogmen wie "C++ muss rein bleiben" auf Kosten von Seiteneffekten fordert, mag zwar reineren C++ Code schreiben, wartbarer und fehlerfreier wird der Code damit aber nicht.

Doch doch, erstens wird er wartbarer, und zweitens fehlerfreier. Da bin ich wohl genau gegenteiliger Meinung zu dir. :)

Im Gegensatz zu ...

cout << f;

... hat ...

printf("%f", f);

... gleich zwei (evtl. sogar zwei einhalb) leicht vermeidbare Fehlerquellen, die vom Compiler nur bedingt erkannt werden. Übersichtlicher wird der Code durch printf() nicht, und die Sache mit dem State regelt man normalerweise beim Betreten und Verlassen der eigenen Lib.

Im Übrigen dienen "Dogmen" oftmals dazu, Leuten denen entscheidende Infos fehlen, vor Hindenbugs, Heisenbugs, Schrödingbugs oder Mandelbugs zu bewahren. Im vorliegenden Falle würde dieses Dogma also auch "dich" davor schützen, die komplette Ausgabe eines Programms ins Chaos zu stürzen. D. h. wenn du dich denn darauf einlassen würdest.

Trotzdem hast du auch hier wieder bedingt recht, da viele Dogmen nur um ihrer selbst willen existieren. Die "Reinhaltung von C++" zählt aber offensichtlich ausdrücklich nicht dazu. :)

Also auch wenn C++ Fans offensichtlich leicht ungehalten werden: setprecision ist keine schöne Lösung.

Wer ein wirklicher C++ Fan ist, der wird das zu 100% so unterschreiben. Da bin ich mit dir wieder mal einer Meinung und ich glaube, es gibt kaum C++ler, die das anders sehen werden.

Und es als "höchste Kunst" zu verkaufen und mit threadsafety zu argumentieren ebenfalls nicht.

Habe ich beides nicht getan. Zu deiner Entschuldigung sei erwähnt, dass die Baumdarstellung hier bei GF so unglaublich schlecht ist, dass ich bei längeren Diskussionen auch nicht mehr weiß, wem ich eigentlich antworte, oder wer was wann gesagt hat. :)

Ich kenne viele C++ Großprojekte, die genau an solchen Seiteneffekten scheiterten.

Scheitern? Ein Projekt wird komplett eingestellt, weil niemand es geschafft hat, bei der Ausgabe von Gleitpunktzahlen in die Standardausgabe, den State zu pushen und zu poppen?

Wenn ein Projekt an so etwas scheitert, dann liegt das aber mit Sicherheit NICHT an der Implementierung der STL, sondern hat seine Ursachen ganz woanders. :)

Also Projekte sind daran zwar noch nicht gescheitert, aber printf() in C++ Code hat in meinem Umfeld schon mehrfach zu mehrtägigen Debugging-Sessions geführt. :)

Vielleicht können wir etwas ruhiger argumentieren?

Das tun wir gerade. :)

Kommentar von TeeTier ,

PS: Ich schrieb ...

... gleich zwei (evtl. sogar zwei einhalb) leicht vermeidbare Fehlerquellen, ...

... und dabei habe sogar das Wichtigste ausgeblendet. Es sind also sogar drei leicht vermeidbare Fehlerquellen, und nicht nur zwei. Die Methode mit "cout <<" ist "printf()" also deutlich überlegen, selbst schon bei so einem kurzen Minisnippet. :)

Keine passende Antwort gefunden?

Fragen Sie die Community