Spec-Zone.ru › C

Инициализация скаляров

При инициализации объекта скалярного типа инициализатор должен быть единственным выражением

Инициализатор для скаляра (объекта целочисленного типа, включая булевы и перечислимые типы, типов с плавающей точкой, включая комплексные и мнимые, и указателей, включая указатели на функции) должен быть единственным выражением, необязательно заключённым в фигурные скобки, или пустым инициализатором(с C23):

= выражение (1)
= { выражение } (2)
= { } (3) (с C23)
1,2) Выражение вычисляется, и его значение после преобразования, как при присваивании к типу объекта, становится начальным значением инициализируемого объекта.
3) Объект пусто инициализируется, то есть инициализируется нулевым значением для объекта арифметического или перечислимого типа или значением нулевого указателя для объекта типа указатель.

Примечания

Из-за правил, применяемых к преобразованиям как при присваивании, const и volatile квалификаторы объявленного типа игнорируются при определении типа, к которому преобразуется выражение.

См. инициализацию для правил, применяемых, когда инициализатор не используется.

Как и при всех других инициализациях, выражение должно быть константным выражением при инициализации объектов статического или локального для потока хранения.

Выражение не может быть оператором запятой (за исключением случая, когда он заключен в скобки), так как запятая на верхнем уровне будет интерпретирована как начало следующего декларатора.

При инициализации объектов типа с плавающей точкой все вычисления для объектов с автоматическим временем хранения выполняются как будто во время выполнения и зависят от текущего округления; ошибки с плавающей точкой сообщаются в соответствии со спецификациями math_errhandling. Для объектов со статическим и локальным для потока временем хранения вычисления выполняются как будто во время компиляции и исключения не генерируются:

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float v = 1.1e75; // does not raise exceptions: static init
 
    float u[] = { 1.1e75 }; // raises FE_INEXACT
    float w = 1.1e75;       // raises FE_INEXACT
 
    double x = 1.1e75; // may raise FE_INEXACT (depends on FLT_EVAL_METHOD)
    float y = 1.1e75f; // may raise FE_INEXACT (depends on FLT_EVAL_METHOD)
 
    long double z = 1.1e75; // does not raise exceptions (conversion is exact)
}

Пример

#include <stdbool.h>
int main(void)
{
    bool b = true;
    const double d = 3.14;
    int k = 3.15; // conversion from double to int
    int n = {12}, // optional braces
       *p = &n,   // non-constant expression OK for automatic variable
       (*fp)(void) = main;
    enum {RED, BLUE} e = RED; // enumerations are scalar types as well
}

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
    • 6.7.9/11 Инициализация (с. 101)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 6.7.9/11 Инициализация (с. 140)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 6.7.8/11 Инициализация (с. 126)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
    • 6.5.7 Инициализация

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/scalar_initialization

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API