Namespaces
Variants

Scalar initialization

From cppreference.net

Beim Initialisieren eines Objekts vom skalaren Typ muss der Initialisierer ein einzelner Ausdruck sein

Der Initialisierer für einen Skalar (ein Objekt von Ganzzahltyp inklusive Boolesche und Aufzählungstypen, Gleitkommatyp inklusive komplex und imaginär, sowie Zeigertyp inklusive Zeiger auf Funktion) muss ein einzelner Ausdruck sein, optional in geschweiften Klammern eingeschlossen , oder ein leerer Initialisierer (seit C23) :

= Ausdruck (1)
= { Ausdruck } (2)
= { } (3) (seit C23)
1,2) Der Ausdruck wird ausgewertet und sein Wert wird nach Konvertierung wie durch Zuweisung zum Typ des Objekts zum Anfangswert des zu initialisierenden Objekts.
3) Das Objekt wird leer-initialisiert , d.h. auf numerisch Null für ein Objekt eines arithmetischen oder Aufzählungstyps initialisiert, oder auf einen Nullzeigerwert für ein Objekt eines Zeigertyps.

Hinweise

Aufgrund der Regeln, die für Konvertierungen wie durch Zuweisung gelten, werden const und volatile Qualifizierer des deklarierten Typs ignoriert, wenn bestimmt wird, in welchen Typ der Ausdruck konvertiert werden soll.

Siehe initialization für die Regeln, die angewendet werden, wenn kein Initialisierer verwendet wird.

Wie bei allen anderen Initialisierungen muss expression ein constant expression sein, wenn Objekte mit statischer oder Thread-lokaler storage duration initialisiert werden.

Der Ausdruck kann kein Komma-Operator sein (sofern nicht in Klammern gesetzt), da das Komma auf oberster Ebene als Beginn des nächsten Deklarators interpretiert werden würde.

Bei der Initialisierung von Objekten vom Gleitkommatyp werden alle Berechnungen für Objekte mit automatischer Speicherdauer so durchgeführt, als ob sie zur Ausführungszeit stattfinden, und werden durch die aktuelle Rundungsart beeinflusst; Gleitkommafehler werden gemäß math_errhandling gemeldet. Für Objekte mit statischer und thread-lokaler Speicherdauer werden Berechnungen so durchgeführt, als ob sie zur Kompilierzeit stattfinden, und es werden keine Ausnahmen ausgelöst:

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float v = 1.1e75; // löst keine Exceptions aus: statische Initialisierung
    float u[] = { 1.1e75 }; // löst FE_INEXACT aus
    float w = 1.1e75;       // löst FE_INEXACT aus
    double x = 1.1e75; // kann FE_INEXACT auslösen (abhängig von FLT_EVAL_METHOD)
    float y = 1.1e75f; // kann FE_INEXACT auslösen (abhängig von FLT_EVAL_METHOD)
    long double z = 1.1e75; // löst keine Exceptions aus (Konvertierung ist exakt)
}

Beispiel

#include <stdbool.h>
int main(void)
{
    bool b = true;
    const double d = 3.14;
    int k = 3.15; // Konvertierung von double zu int
    int n = {12}, // optionale geschweifte Klammern
       *p = &n,   // nicht-konstanter Ausdruck OK für automatische Variable
       (*fp)(void) = main;
    enum {RED, BLUE} e = RED; // Aufzählungen sind ebenfalls skalare Typen
}

Referenzen

  • C17-Standard (ISO/IEC 9899:2018):
  • 6.7.9/11 Initialisierung (S: 101)
  • C11-Standard (ISO/IEC 9899:2011):
  • 6.7.9/11 Initialization (S. 140)
  • C99 Standard (ISO/IEC 9899:1999):
  • 6.7.8/11 Initialisierung (S. 126)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 6.5.7 Initialisierung