Namespaces
Variants

Scalar initialization

From cppreference.net

Al inicializar un objeto de tipo escalar , el inicializador debe ser una única expresión

El inicializador para un escalar (un objeto de tipo entero incluyendo booleanos y tipos enumerados, tipo flotante incluyendo complejo e imaginario, y tipo puntero incluyendo puntero a función) debe ser una única expresión, opcionalmente entre llaves , o un inicializador vacío (desde C23) :

= expresión (1)
= { expresión } (2)
= { } (3) (desde C23)
1,2) La expresión es evaluada, y su valor, después de conversión como si fuera por asignación al tipo del objeto, se convierte en el valor inicial del objeto que se está inicializando.
3) El objeto es inicializado-vacío , es decir, inicializado a cero numérico para un objeto de tipo aritmético o de enumeración, o valor de puntero nulo para un objeto de tipo puntero.

Notas

Debido a las reglas que se aplican a las conversiones como si fuera por asignación, const y volatile calificadores en el tipo declarado se ignoran al determinar a qué tipo convertir la expresión .

Consulte inicialización para las reglas que se aplican cuando no se utiliza ningún inicializador.

Como con todas las demás inicializaciones, expression debe ser una constant expression al inicializar objetos de storage duration estática o thread-local.

La expresión no puede ser un operador coma (a menos que esté entre paréntesis) porque la coma en el nivel superior sería interpretada como el inicio del siguiente declarador.

Al inicializar objetos de tipo punto flotante, todos los cálculos para los objetos con duración de almacenamiento automática se realizan como si fuera en tiempo de ejecución y se ven afectados por el modo de redondeo actual ; los errores de punto flotante se reportan según lo especificado en math_errhandling . Para objetos con duración de almacenamiento estática y local de hilo, los cálculos se realizan como si fuera en tiempo de compilación, y no se generan excepciones:

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float v = 1.1e75; // no genera excepciones: inicialización estática
    float u[] = { 1.1e75 }; // genera FE_INEXACT
    float w = 1.1e75;       // genera FE_INEXACT
    double x = 1.1e75; // puede generar FE_INEXACT (depende de FLT_EVAL_METHOD)
    float y = 1.1e75f; // puede generar FE_INEXACT (depende de FLT_EVAL_METHOD)
    long double z = 1.1e75; // no genera excepciones (la conversión es exacta)
}

Ejemplo

#include <stdbool.h>
int main(void)
{
    bool b = true;
    const double d = 3.14;
    int k = 3.15; // conversión de double a int
    int n = {12}, // llaves opcionales
       *p = &n,   // expresión no constante OK para variable automática
       (*fp)(void) = main;
    enum {RED, BLUE} e = RED; // las enumeraciones también son tipos escalares
}

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.7.9/11 Inicialización (p: 101)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.7.9/11 Inicialización (p: 140)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.7.8/11 Inicialización (p: 126)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 6.5.7 Initialization