C++ - etwas Kontroverses zum Jahresende

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
starcow
Establishment
Beiträge: 588
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Wohnort: Zürich
Kontaktdaten:

C++ - etwas Kontroverses zum Jahresende

Beitrag von starcow »



*duck - und weg*
Nein, Spass! Ich bin vor einiger Zeit auf dieses Video gestossen und kann es euch nicht vorenthalten.
Meine Kompetenz in C++ reicht für viele seiner Positionen nicht aus, um diese wirklich beurteilen zu können.

1:15:30 ist allerdings klar falsch, da weder in C, noch in C++ eine unvollständige (Teil-) Initialisierung möglich ist (nicht explizit initialisierte Komponenten eines struct oder class werden bei einer Teil-Initialisierung bekanntlich mit dem Wert 0 initialisiert).

Wie beurteilt ihr diese "Abrechnung"? Wo hat er recht - wo nicht?

Euch allen einen schönen Slivester!
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8399
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Krishty »

Ich werde das wahrscheinlich nicht ganz schauen, aber betreffend diese eine Folie über Initialisierung dürftest du richtig liegen. Konkret: nicht initialisierte Member werden default-initialisiert; für native Typen entspricht die Default Initialization einer Value Initialization mit 0. Spricht nicht für die Sprache, beruhigt dich aber hoffentlich. Frohes Neues!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2874
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Jonathan »

starcow hat geschrieben: 31.12.2025, 16:19 *duck - und weg*
Ich war als Teenager vermutlich ein unerträglicher Fanboy, aber nur weil ich immer noch (für Spieleentwicklung) bevorzugt C++ verwende, heißt das heutzutage nicht, dass ich nicht viel daran kritisieren könnte. Damals wäre mir so ein Video also vlt. sauer aufgestoßen, heute bin ich da tatsächlich etwas erwachsener, wie ich mir einbilden möchte.

Ich habs jetzt auch noch nicht geguckt, aber was mir auch ohne das klar ist, ist, dass C++ super viele schlimme Altlasten hat, die man auch nicht so einfach los werden kann. Vieles was moderne Sprachen heute besser machen, wird man also einfach nie los werden. Oh well :D

Witzigerweise wollte ich mal zu Rust überwechsel, hab dann aber aufgrund eines ähnlichen Artikels den Schritt nie gemacht:

https://loglog.games/blog/leaving-rust-gamedev/

Vielleicht schau ich mir das andere Video auch irgendwann mal an, aber ehrlich gesagt, erwarte ich nicht viel praxisrelevantes davon. Auch 1-12 neue Kritikpunkte werden mich nicht mein Verhalten ändern lassen, hauptsächlich, weil ich dann ja meine Jahrzehnte alte Codebase aufgeben müsste. Das wird so schnell nicht passieren.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2874
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Jonathan »

starcow hat geschrieben: 31.12.2025, 16:19 Wie beurteilt ihr diese "Abrechnung"? Wo hat er recht - wo nicht?
Hab mal anlässlich eines eigenes Problems kurz reingeschaut. Ein paar Punkte die er anspricht erscheinen mir etwas naiv ("guck mal wie hässlich das ist" - ja, weil man das so halt auch nicht machen soll...), aber andere Dinge stimmen halt auch.

Gestern wollte ich eine Referenz auf ein Element in einen std::vector speichern. Ich wollte die Position wissen, weswegen Zeiger rausfielen, also dachte ich mir, das "schönste" wäre wohl ein Iterator. Aber meine Referenz muss auch auf gar nichts verweisen können, was natürlich mit einem .end() geht - bloß leider werden Iteratoren ungültig, wenn sich der Vektor ändert. Ich müsste also jedes mal wenn ich ein Element hinzufügen will vorher prüfen ob meine Referenz end() war und dann danach aktualisieren. Ja, ne, da nehm ich doch lieber einen int. Den kann ich auf -1 prüfen, das funktioniert immer, und er hat auch nicht wirklich irgendwelche Nachteile gegenüber Iteratoren. Danke für gar nichts...

(Für Container wie std::list sind Iteratoren wohl weniger nutzlos, und vermutlich hat der std::vector sie auch nur bekommen, damit es einheitlich ist, und nicht, weil Iteratoren für vectoren irgendwie nützlich wären - zumindest fällt mir kein echter Nutzen ein...)
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
starcow
Establishment
Beiträge: 588
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Wohnort: Zürich
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von starcow »

Krishty hat geschrieben: 01.01.2026, 03:01 für native Typen entspricht die Default Initialization einer Value Initialization mit 0. Spricht nicht für die Sprache, beruhigt dich aber hoffentlich. Frohes Neues!
Ist doch eine gute Sache, wenn fehlende explizite Initialisierung einheitlich zur 0-Initialisierung wird. Eine Verlässliche Regel ohne Überraschungen.
Oder hast du das anders gemeint?
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8399
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Krishty »

Value Initialization == Zero Initialization gilt aber nur für native Typen. Wenn du Klassen dazwischen hast, deren K’toren Attribute nicht initialisieren, bleiben die uninitialisiert.

Code: Alles auswählen

struct Foo {
    int x;
    Foo() = default;
};

Foo foo{ }; // foo.x wird NICHT initialisiert
Das ist alles kein Problem, wenn du dich durchgängig an die Richtlinien zur Initialisierung hälst, und alles brav definierst und Standardwerte hinzufügst. Das ist aber, worauf ich hinaus wollte: Du musst bei allem, was du tust, immer obskure Richtlinien befolgen.

C hat dem gegenüber 0-Initialisierung für alles, was nicht in Initializer Lists definiert wird.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2874
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Jonathan »

Ja, glm hat mal irgendwann aufgehört alle Vectoren mit 0 zu initialisieren, außer man macht das explizit. Stand auch irgendwo im Changelog, aber wenn man halt 20 Versionen überspringt (weil sich immer Kleinigkeiten ändern, die mich nicht betreffen) übersieht man das sehr sehr leicht. Ich durfte dann erstmal herausfinden, warum meine Projekte auf einmal alle Random crashen, dann herausfinden, dass es an der neuen glm Version lag, dann herausfinden, dass es an der geänderten Initialisierung lag und dann in meiner kompletten Codebase absolut alle Initialisierungen von allen glm Klassen doppelt überprüfen, weil auch nach Tagen des Suchens immer noch irgendwo manchmal irgendwas explodiert ist.

Das war ein totaler Riesenspaß...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8399
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Krishty »

Ich bin total für uninitialisierten Speicher und uninitialisierte Variablen, so lange das umgebende Regelwerk halt einfach ist. Ist es in C++ aber nicht
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1750
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von dot »

Krishty hat geschrieben: 10.01.2026, 10:58

Code: Alles auswählen

struct Foo {
    int x;
    Foo() = default;
};

Foo foo{ }; // foo.x wird NICHT initialisiert
fun fact: foo.x wird hier zero-initialized weil wir es mit value-initialization zu tun haben und der constructor nicht user-provided ist [dcl.init.general]/9.1
Benutzeravatar
dot
Establishment
Beiträge: 1750
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von dot »

starcow hat geschrieben: 31.12.2025, 16:19 Wie beurteilt ihr diese "Abrechnung"? Wo hat er recht - wo nicht?
Das Video ging eine ganze Weile um, ist effektiv einfach nur ein Bilderbuchbeispiel für Click-/Ragebait, brauchst dir nur den Titel und Thumbnail anzuschauen. Der Inhalt reicht von oberflächlich und irrelevant über selbstwidersprüchlich bis hin zu fehlgeleitet und einfach nur falsch.
Benutzeravatar
Krishty
Establishment
Beiträge: 8399
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Krishty »

dot hat geschrieben: 14.01.2026, 16:54fun fact: foo.x wird hier zero-initialized weil wir es mit value-initialization zu tun haben und der constructor nicht user-provided ist [dcl.init.general]/9.1
Danke für die Korrektur!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 631
Registriert: 05.07.2003, 11:17

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Lord Delvin »

Jonathan hat geschrieben: 01.01.2026, 17:42 Witzigerweise wollte ich mal zu Rust überwechsel, hab dann aber aufgrund eines ähnlichen Artikels den Schritt nie gemacht:

https://loglog.games/blog/leaving-rust-gamedev/
Eigentlich wollte ich seit Tagen was dazu schreiben, bin aber irgendwie nicht dazu gekommen.
Der Akademiker in mir sagt *MUST* Ownership, aber das hat sich in der Vergangenheit als nicht wirklich erklärbarer Gedanke entpuppt: Im Kern war von Anfang an klar, dass die Rustkollegen das falsche Ownershipkonzept genommen haben und alles, was die Welt jetzt in der Praxis sieht war eigentlich von vornherein klar, weil die Regel schlicht zu strikt ist, um in der Praxis hilfreich zu sein. Zum Scheitern verdammt, wie auch alle anderen Versuche irgendwas zu bauen, das zu sicher oder zu definiert ist. Ein bisschen UB ist immer; die Frage ist eigentlich, ob die Autoren das verstehen und klar kommunizieren und erklären können, warum es eine gute Idee ist (ist es oft wenn sie's erklären können). Den Vergleich mit Haskell finde ich sehr passend; das hatte ich auch immer wieder so wahrgenommen; vermutlich wird's einfach eine Nieschensprache für Embedded, weil Fanatismus untragbar geringe Produktivität einfach nicht ausgleichen kann.

Zum uninitialisierten Speicher wollte ich eigentlich auch noch was längeres schreiben; die Kurzfassung ist, dass ich das in Tyr als explizites Ziel hatte, hier irgendwas vernünftiges zu liefern, weil man bei der Performanceevaluation meiner Diss gesehen hat, dass die Mehrfachinitialisierung, die man sonst hat einfach kostet. In dem Fall ist es besonders ärgerlich, weil man für Zeroinitializer Zahlen muss und dann bevor der User das Objekt sehen kann noch aus der Datei Werte liest und drüberschreibt, was manchmal genausoteuer ist (angenommen IO ist gut genug oder die Datei ist zum Lesen im RAM gecacht, was in dem use case tatsächlich sehr häufig der Fall ist). Die Wahrheit hier ist, dass es sehr sehr schwer ist ein Verhalten aufzuschreiben, dass effizient ist und den Erwartungen eines Nutzers (aka mir selbst, weil ich vermutlich der einzige user bin) entspricht. An der Ecke entsteht durch Interaktion mit anderen Spracheigenschaften viel Reibung und UB. Z.B. ist vollkommen unklar, was mit impliziten Initialisierungen ist oder impliziten Konstruktoren bei teilweise expliziten Initialisierungen. Wenn man z.B. per shortcut assignment ein Feld initialisiert und ein weiteres uninitialisiert definiert und keinen expliziten Konstruktor hat, ist das uninitialisierte dann uninitialisiert oder zeroinitialisiert? Wie würde man explizit uninitialisierte Felder definieren (eine magische Konstante bräuchte einen Typ)? Will man das?
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Benutzeravatar
Jonathan
Establishment
Beiträge: 2874
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Jonathan »

Lord Delvin hat geschrieben: 15.01.2026, 22:22 Zum uninitialisierten Speicher wollte ich eigentlich auch noch was längeres schreiben; die Kurzfassung ist, dass ich das in Tyr als explizites Ziel hatte, hier irgendwas vernünftiges zu liefern, weil man bei der Performanceevaluation meiner Diss gesehen hat, dass die Mehrfachinitialisierung, die man sonst hat einfach kostet.
Es gibt aus meiner Sicht sogar doppelte Kosten. Ich hab an meinen Widgetklassen rumgebaut und manche haben halt mehrere, recht verschiedene Konstruktoren, die entsprechend jeweils Werte initialisieren. Was ich darum jetzt mache ist, alle Member die überall gleich initialisiert werden schon im Header zu setzen (Fachbegriff vergessen, egal, sollte klar sein) und die anderen in der Implementierung in der Initialisierungsliste, oder, wenn vorher ein bisschen Code passieren muss bevor ich den Wert kenne, halt im Rumpf.

Ich mag es nicht, Werte mehrmals zu setzen, nicht weil das langsamer ist, sondern weil es unübersichtlicher ist. Vielleicht ändere ich später mal meine Meinung, will einen neuen Standardwert haben. Jetzt vergesse ich aber die Hälfte der Konstruktoren zu aktualisieren und meine Objekte haben manchmal den neuen Standardwert, manchmal noch den alten. Und schon ist alles kaputt. Einen Zeiger mit 0 zu initialisieren ist dabei eine Sache, das fällt eh auf, aber z.B. das Padding von 8 Pixel auf 12 Pixel zu ändern, aber eben nicht immer - das ist nervig und das will ich vermeiden.

Ich hatte übrigens erst vorgestern das Problem, dass ein Array-Index in manchen Konstruktoren überhaupt nicht initialisiert war, was zu subtilen Abstürzen geführt hat. Ich war sehr enttäuscht, dass es dazu keine Compilerwarnung gab (ja, man kann vielleicht nicht immer sagen, was der Code garantiert macht, aber in den meisten Fällen halt eben doch - deshalb Warnung und nicht Fehler), und habe dann später herausgefunden, dass die Code-Analyse, die man separat ausführen kann, die uninitialisierte Variable dann doch gefunden hat. Alles klar, beim nächsten komischen Crash ist das dann halt das erste, was ich mache.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Lord Delvin
Establishment
Beiträge: 631
Registriert: 05.07.2003, 11:17

Re: C++ - etwas Kontroverses zum Jahresende

Beitrag von Lord Delvin »

Ich glaube du verstehst was ich sagen wollte ;)

Zur Wahrheit gehört auch, dass man nicht alle Warnungen im Compiler prüfen will, weil das ggf. ziemlich overhead erzeugt und der Compiler dann auch im Gut-Fall langsam ist. Da begleitendes Tooling und eine IDE zu haben, die das Extratooling wie Compilerwarnungen präsentiert ist eigentlich, was man will. Ist aber Aufwand das richtig zu bauen.
XML/JSON/EMF in schnell: OGSS
Keine Lust mehr auf C++? Versuche Tyr: Get & Get started
Antworten