Variablen Initialisierung int var {1};



  • Hallo Zusammen,

    ich bin eher zufällig auf folgende Art der Variablenintialisierung gestoßen:

    int var {1};
    

    Welche den Vorteil bietet, dass man keine Werte zuweisen kann, die keinen "Sinn" ergeben - zum Beispiel:

    int var {1.5}; // Compiler-Error
    
    char var1 {10000}; // Compiler-Error
    
    int var2 = 1.5;  // Hier sagt der Compiler gar nichts
    
    char va3 = 10000; // Immerhin ein Warning
    

    Nun habe ich einige Fragen dazu:

    Zum einen, wie heißt diese Art der Initialisierung für eine Variable eigentlich? Ist sie erst ab einem bestimmten C++ Standard verfügbar (C++11?)?

    Zum anderen, hat diese Art der Initialisierung weitere Vor-/Nachteile? Das einzige was mir negativ auffällt, ist die etwas unangenehmere Schreibweise der geschweiften Klammern im Vergleich zu '=' und ';'.

    Ansonsten würde ich diese Art der Initialisierung einfach pauschal für alle Variablen in meinen Projekten einführen wenn nichts dagegen spricht; schließlich scheint diese Art der Initialisierung strikter vom Compiler geprüft zu werden.

    Vielen Dank und Grüße!



  • Stichwort ist "uniform initialization", seit C++11.

    Siehe z.B. http://www.stroustrup.com/C++11FAQ.html#uniform-init
    oder auch auf Stackoverflow: http://stackoverflow.com/questions/tagged/uniform-initialization



  • Was ich noch vergessen hatte zu schreiben: das Ersetzen geht nicht immer. Prominentestes Beispiel dürfte std::vector sein.

    Vegleiche:

    vector<int> v1(10); // 10 Elemente mit Wert 0
    vector<int> v2{10}; // ein Element mit Wert 10
    


  • Vorteile werden u.a. hier gut beschrieben.

    Besonders was den "Most Vexing Parse" in seinen unterschiedlichen Ausprägungen angeht, wird sich bei der klassischen Initalisierung jeder
    angehende C++-Programmierer früher oder später mal verständnislos am Kopf kratzen.
    Was die pauschale Verwendung angeht: Wenn tatsächlich Konstruktoren aufgerufen werden, bin ich gnz auf deiner Seite.
    Bei primitiven Datentypen (char, int, float, etc.) fände ich es allerdings übertrieben. Hier finde ich dass man ruhig explizit ausschreiben darf,
    was man meint: "Der Integer A soll gleich 42 sein". Auch Strings würde ich diesbezüglich noch ausnahmsweise zu den "primitiven Datentypen" zählen.

    Gruss,
    Finnegan



  • Finnegan schrieb:

    Bei primitiven Datentypen (char, int, float, etc.) fände ich es allerdings übertrieben. Hier finde ich dass man ruhig explizit ausschreiben darf,
    was man meint: "Der Integer A soll gleich 42 sein".

    Hm, gerade bei int finde ich das Hinschreiben gefährlich.

    int grenze = 7;
    

    Und morgen wird das Programm irgendwie geändert, dass auf einmal floating points statt ints erlaubt sind und die Grenze wird zu

    int grenze = 7.2;
    

    und man wundert sich, dass das nicht so funktioniert wie erwartet. Gerade da würde das Narrowing verbietende uniform init helfen.

    Oder aber, und das mache ich lieber:

    auto grenze = 7;
    

    wird zu

    auto grenze = 7.2;
    

    und ist immer noch richtig.

    Von daher: gerade bei int/double hatte ich dieses Problem schon mehrfach.

    Pascal hat nie automatisch float->int konvertiert, fand ich persöndlich sehr viel angenehmer als das kommentarlose Abschneiden der Zahl.



  • Hallo,

    danke für eure Antworten.

    Tatsächlich finde ich es auch für die elementaren Datentypen am schönsten. Für die Initialisierung von Objekten finde ich es auch noch ganz schick, aber um zum Beispiel Konstruktoren in Funktionsrümpfen oder als Rückgabewerte aufzurufen gefällt es mir schon nur noch bedingt (verringert m.E. etwas die Lesbarkeit).

    Zu dem auto habe ich aber noch eine Frage; ich habe folgendes mal als Beispiel gemacht:

    auto i {0};
    i = INT64_MAX;
    cout << i << "\n"
    

    Resultat auf der Console: -1

    Das ist nicht schön. Mir ist natürlich klar, dass der Compiler nicht wissen kann wie groß eine Variable mal wird (insbesondere bei weniger trivialen Code), aber kann man sich dann überhaupt auf auto verlassen? Gibt es eine Art Vorzugsgröße für auto integers / floating points? Falls nein, woran macht der Compiler denn fest, was für ein integer / floating point genutzt wird?

    Viele Grüße!



  • Auto guckt halt, was da auf der rechten Seite so für ein Typ steht (salopp gesprochen, also const reference wird entfernt). Siehe auch http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf

    0 ist ein int (also "normale" Ganzzahlen sind immer int). Wenn du 0.0 schreibst, ist das ein double, 0.0f ein float, 0u ein unsigned, 0l ein long, 0ll ein long long und so weiter. Was in der Zeile danach steht, ist irrelevant.



  • wob schrieb:

    das Ersetzen geht nicht immer. Prominentestes Beispiel dürfte std::vector sein.

    Eigentlich ist es das einzige Beispiel...



  • manni66 schrieb:

    wob schrieb:

    das Ersetzen geht nicht immer. Prominentestes Beispiel dürfte std::vector sein.

    Eigentlich ist es das einzige Beispiel...

    Es stimmt schon dass std::valarray neben ein paar anderen Klassen die es sicherlich außerhalb der Standardbibliothek gibt, nicht sonderlich prominent ist :p



  • Hi Zusammen,

    nochmal zu dem auto Schlüsselwort.

    Es klingt zunächst mal ungemein praktisch. Ist die Angabe von Zahl + Suffix aber nicht genau das was man mit auto umgehen will? Wo liegt der unterschied ob ich jetzt

    auto x = 100ll;
    

    oder

    uint64_t x = 100;
    

    schreibe? Ich lege in beiden Fällen den Typ selbst fest. (Einmal direkt über den Datentyp, mit auto sogar den Umweg des Suffix).

    Gibt es feste Regeln welche Größe z.B. ein int standardmäßig hat? Also kann man sich auf allen Plattformen darauf verlassen das z.B.:

    auto i = 0;
    

    Ein int32_t ist? Oder kann hier von (u)int8_t bis (u)int64_t alles passieren?

    Vielen Dank und Grüße!


  • Mod

    starseed84 schrieb:

    Gibt es feste Regeln welche Größe z.B. ein int standardmäßig hat? Also kann man sich auf allen Plattformen darauf verlassen das z.B.:

    auto i = 0;
    

    Ein int32_t ist?

    Nein, es ist ein int, das ist es, worauf du dich verlassen kannst. int und int32_t sind im Allgemeinen nicht gleich.

    Derzeit gibt es im Standard noch keine eingebaute Methode, Integerliterale mit fester Breite anzugeben. Wenn man es unbedingt braucht, sollte es aber möglich sein, indem man sich entsprechende eigene Literale definiert:
    http://en.cppreference.com/w/cpp/language/user_literal

    auto ist aber eigentlich unbedingt nicht dazu da, Integer bestimmter Größe zu erzeugen, sondern im Gegenteil ist es genau dann gut, wenn der genaue Typ eben nicht wichtig ist, sondern nur, wie er sich verhält.


Log in to reply