Seite 1 von 1

struct C(++) - Syntax Frage

Verfasst: 23.01.2022, 23:39
von starcow
Abend zusammen

Ich bin in einem Stück C(++) Code auf eine Syntax gestossen, die mir so noch nie begegnet ist.
So ganz will mr nicht klar werden, was sie bewirkt.
Etwas abekürzt sieht das ganz folgendermassen aus:

Code: Alles auswählen

const SDL_Rect src = { .x = (int) wert1, .y = (int) wert2, .w = (int) wert3, .h = (int) wert4, };
Soweit ist für mich klar, dass eine konstante Struktur SDL_Rect mit dem Bezeichner src deklariert wird. Dabei wird sie offensichtlich gleich konkret definiert (mit Werten gefüllt), welche zuvor in einen int gecastet wurden.
Nur verstehe ich diese "verschachtelte° Zuweisung an .x .y .w .h nicht. Und irgenwie scheint mir da ein Komma zuviel dabei zu sein (Am Ende, nach wert4).

Gruss starcow

Re: struct C(++) - Syntax Frage

Verfasst: 24.01.2022, 00:28
von Matthias Gubisch
Dein Stichwort für google ist
Aggregate Initialization bzw. Designated Initializers

Referenz:
https://en.cppreference.com/w/cpp/langu ... ialization

Kurze Erklärung:
https://www.modernescpp.com/index.php/d ... itializers

Das Komma ist überflüssig ja, der Compiler ignoriert es aber wenn mich nicht alles täuscht.

Re: struct C(++) - Syntax Frage

Verfasst: 24.01.2022, 01:18
von Krishty
Matthias Gubisch hat geschrieben: 24.01.2022, 00:28Das Komma ist überflüssig ja, der Compiler ignoriert es aber wenn mich nicht alles täuscht.
Genau, aber bis zum 0x-Standard war das tatsächlich noch ein Syntaxfehler. Starcows Misstrauen war schon richtig :)

Re: struct C(++) - Syntax Frage

Verfasst: 24.01.2022, 09:19
von Jonathan
initialization.mp4
(578.34 KiB) 86-mal heruntergeladen

Re: struct C(++) - Syntax Frage

Verfasst: 24.01.2022, 11:04
von Lord Delvin
Das mit dem Komma wird bzw. wurde in relativ vielen Sprachen mit der Zeit nachgerüstet, weil es zum Parsen egal ist und es schlechten Programmierern hilft Code zu generieren.

Re: struct C(++) - Syntax Frage

Verfasst: 24.01.2022, 11:12
von joggel
Lord Delvin hat geschrieben: 24.01.2022, 11:04 ...und es schlechten Programmierern hilft Code zu generieren.
🤎

Hab gehört aus diesem Grund wurde Github Copilot ins Leben gerufen :)

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 11:03
von starcow
Achso x, y, w, h sind Komponenten von der SDL_Rect Struktur!
Dadurch wird also die Reihenfolge egal, in welcher ich den Komponenten der Struktur Werte zuweise?
Oder anders formuliert: Damit hat man eine Absicherung das mit .x = 50 wirklich x initialisiert wird - auch wenn durch die gegebene Reihenfolge in der Struktur, ohne spezifisches x = 50, eigentlich y initialisiert worden wäre, richtig?
Insofern eigentlich eine sinnvolle Ergänzung, oder?
Ich nehme an, dieses Feature gibts nur unter C++ - und nicht für reines C?

Was ist den der Vorteil, wenn die Sprache so viele Arten der Initialisierung von Strukturen erlaubt? Habe mr die verlinkte CPP-Referenzseite eben angesehen. Das sind doch schon einige... Läuft man da nicht Gefahr, dass eine Sprache dadurch verwässert wird?
Lord Delvin hat geschrieben: 24.01.2022, 11:04 Das mit dem Komma wird bzw. wurde in relativ vielen Sprachen mit der Zeit nachgerüstet, weil es zum Parsen egal ist und es schlechten Programmierern hilft Code zu generieren.
Im Ernst... Ein anderer Grund kann einem da jetzt nicht wirklich einfallen? Aber dies kann wohl nicht der tatsächliche Grund gewesen sein. Eine solche Prämisse wäre doch entgegen jeglicher Sprach-Design-Grundsätze!

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 13:25
von Schrompf
starcow hat geschrieben: 26.01.2022, 11:03 Achso x, y, w, h sind Komponenten von der SDL_Rect Struktur!
Exakt, Du benennst damit die Member, die Du initialisieren willst.
Dadurch wird also die Reihenfolge egal, in welcher ich den Komponenten der Struktur Werte zuweise?
Oder anders formuliert: Damit hat man eine Absicherung das mit .x = 50 wirklich x initialisiert wird - auch wenn durch die gegebene Reihenfolge in der Struktur, ohne spezifisches x = 50, eigentlich y initialisiert worden wäre, richtig?
Nein. Die Member, die Du initialisierst, müssen trotzdem in der Reihenfolge sein, in der sie in der Struktur stehen. Weil C++ Lifetime Scope Gedöns. Aber Du kannst Member auslassen, die werden dann default-initialisiert. Es ist aber primär ein Feature für den Menschen, nicht für die Maschine. Es macht den Unterschied zwischen

Code: Alles auswählen

SomeStruct stuff{ .x = 13, .y = 25, .w = 43, .h = 36 };
und

Code: Alles auswählen

SomeStruct stuff{ 13, 25, 43, 36 };
Was bedeutet jetzt was? Wenn jetzt eine Kollegin die Codebase liest, sieht sie in V1 sofort, was es bedeutet.

Ich nehme Designated Initialization inzwischen ganz gerne.
Ich nehme an, dieses Feature gibts nur unter C++ - und nicht für reines C?
Nein. Das gibt's seit Ewigkeiten in C. Und es ist mit C++17 oder 20 erst für C++ nachgepflegt worden, weil's da halt viel mehr Corner Cases und Ärger geben kann.
Was ist den der Vorteil, wenn die Sprache so viele Arten der Initialisierung von Strukturen erlaubt? Habe mr die verlinkte CPP-Referenzseite eben angesehen. Das sind doch schon einige... Läuft man da nicht Gefahr, dass eine Sprache dadurch verwässert wird?
Jupp. C++ wird inzwischen für Leute entwickelt, die das seit 10+ Jahren machen. Neulinge sterben einen Heldentod, würde ich vermuten.
Im Ernst... Ein anderer Grund kann einem da jetzt nicht wirklich einfallen? Aber dies kann wohl nicht der tatsächliche Grund gewesen sein. Eine solche Prämisse wäre doch entgegen jeglicher Sprach-Design-Grundsätze!
Es ist nur Syntax. Ich hege da keine Gefühle. Ich mach es ganz gern bei irgendwelchen Enums oder Arrays, die ich gelegentlich mal erweitern muss. Da isses einfach bequem, am Ende gefahrlos ein Komma hängenlassen zu können.

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 16:13
von kaiserludi
Lord Delvin hat geschrieben: 24.01.2022, 11:04 Das mit dem Komma wird bzw. wurde in relativ vielen Sprachen mit der Zeit nachgerüstet, weil es zum Parsen egal ist und es schlechten Programmierern hilft Code zu generieren.
Nein, das ist nicht der Grund dafür.

Der Grund ist vielmehr folgender:
Wenn ich den vom Threadersteller gezeigten Code wie folgt mehrzeilig formatiere

Code: Alles auswählen

const SDL_Rect src =
                               {
                                   .x = (int) wert1,
                                   .y = (int) wert2,
                                   .w = (int) wert3,
                                   .h = (int) wert4,
                               };
dann kann ich nun später im Zuge einer Änderung die vierte Zeile entfernen oder eine fünfte Zeile hinzufügen, ohne dabei die jeweils vorherige Zeile anfassen und dort ein Komma entfernen/ergänzen zu müssen.
Entsprechend habe ich weniger unnötiges Hintergrundrauschen im Versionierungssystem, wenn ich später einmal wissen will, wann welche Zeile wie verändert wurde, denn wenn ich gezielt nach Änderungen an Zeile X Suche, dann interessiert mich ein hinzugefügtes oder entferntes Komma aufgrund einer Änderung in der Folgezeile herzlich wenig, so dass es nützlich ist, wenn ich solche "nur Komma hinzugefügt/entfernt Änderungen" gar nicht erst sehe, weil sie nie nötig waren und ich somit relevante Änderungen schneller finden kann.

Das ist zwar nur eine Kleinigkeit, aber Kleinvieh macht bekanntlich auch Mist.

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 16:23
von Lord Delvin
Wenn das so wäre, wäre meine Frage, warum man das sonst nicht macht. Man könnte es ja auch bei normalen Konstruktor oder Funktionsaufrufen erlauben; da sehe ich das aber nicht, oder irre ich mich?

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 19:08
von kaiserludi
Das gibts bei enums ebenfalls und zwar erst seit C99 und C++11. Vorher wars auch da nicht erlaubt.
Bei Konstruktor Initializer Listen kann man das Ganze lösen, indem man das Komma an den Zeilenanfang statt an das Zeilenende packt:

Code: Alles auswählen

Foo::Foo(int param0, float param1, bool param2)
: var0(param0)
, var1(param1)
, var2(param2)
{
}
Warum das Erlauben eines extra Kommas am Ende nicht auch in Initializer Listen und bei den Parameterlisten von Funktionen eingeführt wurde, kann ich dir nicht sagen. Vielleicht wars dort bisher einfach niemandem wichtig genug.

Die Frage gilt aber für deine Argumentation genauso:
Warum nicht auch in Initializer Listen und bei den Parameterlisten von Funktionen damit schlechten Programmierern helfen, Code zu generieren?

Re: struct C(++) - Syntax Frage

Verfasst: 26.01.2022, 20:27
von Jonathan
kaiserludi hat geschrieben: 26.01.2022, 19:08 Bei Konstruktor Initializer Listen kann man das Ganze lösen, indem man das Komma an den Zeilenanfang statt an das Zeilenende packt:
Naja, da ist dann aber die erste Zeile anders als alle anderen, vorher war es die letzte, man hat also nichts gewonnen?

Aus praktischer Erfahrung muss ich sagen, dass dieses umsortieren öfter vorkommt, als man meinen mag. Vielleicht hat man eine Funktion geändert und muss jetzt bei jedem Aufruf die Parameter umsortieren, oder man hat einen Format-String, oder oder oder. Ich mach das immer gerne mit der Maus (markieren und ziehen) und es ist echt nervig wenn man danach die Komma wieder richtig rücken muss. Es ist echt eine total unwichtige Kleinigkeit, aber wenn es halt nix kostet das zu unterstützen, kann man es ja ruhig auch erlauben.

Re: struct C(++) - Syntax Frage

Verfasst: 28.01.2022, 19:21
von Lord Delvin
kaiserludi hat geschrieben: 26.01.2022, 19:08 Die Frage gilt aber für deine Argumentation genauso:
Warum nicht auch in Initializer Listen und bei den Parameterlisten von Funktionen damit schlechten Programmierern helfen, Code zu generieren?
Tatsächlich ist meine Erfahrung, dass man selten Aufrufe generiert, die leer sein *könnten*. Das ist bei der Generierung von Typen und Initialisierung in der Regel anders.
Wir können uns aber gerne darauf einigen, dass beides Spekulation ist ;)

Re: struct C(++) - Syntax Frage

Verfasst: 23.09.2023, 16:44
von starcow
Schrompf hat geschrieben: 26.01.2022, 13:25
Dadurch wird also die Reihenfolge egal, in welcher ich den Komponenten der Struktur Werte zuweise?
Oder anders formuliert: Damit hat man eine Absicherung das mit .x = 50 wirklich x initialisiert wird - auch wenn durch die gegebene Reihenfolge in der Struktur, ohne spezifisches x = 50, eigentlich y initialisiert worden wäre, richtig?
Nein. Die Member, die Du initialisierst, müssen trotzdem in der Reihenfolge sein, in der sie in der Struktur stehen. Weil C++ Lifetime Scope Gedöns. Aber Du kannst Member auslassen, die werden dann default-initialisiert. Es ist aber primär ein Feature für den Menschen, nicht für die Maschine. Es macht den Unterschied zwischen (...)
Interessant. Ich realisiere erst jetzt, dass dies tatsächlich ein Unterschied zu C darstellt. Die Designated Initializiers in C verarbeiten die Komponenten auch in beliebiger Reihenfolge.

Re: struct C(++) - Syntax Frage

Verfasst: 23.09.2023, 18:05
von Jonathan
starcow hat geschrieben: 23.09.2023, 16:44Ich realisiere erst jetzt,
20 Monate nachdenken ist tatsächlich etwas lang, aber besser spät als nie :)


(sorry, aber bei der Vorlage konnte ich einfach nicht widerstehen, hehe)

Re: struct C(++) - Syntax Frage

Verfasst: 23.09.2023, 20:21
von starcow
Jonathan hat geschrieben: 23.09.2023, 18:05
starcow hat geschrieben: 23.09.2023, 16:44Ich realisiere erst jetzt,
20 Monate nachdenken ist tatsächlich etwas lang, aber besser spät als nie :)

(sorry, aber bei der Vorlage konnte ich einfach nicht widerstehen, hehe)
Ich hatte täglich darüber gebrütet: "Hmmmm, ..., hmmmm, warte, ..., nein, hmmm" ;)

Re: struct C(++) - Syntax Frage

Verfasst: 23.09.2023, 22:07
von Schrompf
:-D