Scalar initialization
При инициализации объекта скалярного типа инициализатор должен быть единственным выражением
Инициализатор для скалярного типа (объекта целочисленного типа, включая логические и перечислимые типы, типа с плавающей точкой, включая комплексные и мнимые, и указательного типа, включая указатель на функцию) должен быть единственным выражением, опционально заключенным в фигурные скобки , или пустым инициализатором (начиная с C23) :
=
выражение
|
(1) | ||||||||
=
{
выражение
}
|
(2) | ||||||||
=
{
}
|
(3) | (начиная с C23) | |||||||
Примечания
Из-за правил, применяемых к преобразованиям как при присваивании,
const
и
volatile
квалификаторы объявленного типа игнорируются при определении типа, к которому следует преобразовать
выражение
.
См. инициализация для правил, применяемых когда инициализатор не используется.
Как и при всех других инициализациях, expression должно быть constant expression при инициализации объектов со статической или thread-local storage duration .
Выражение expression не может быть оператором запятой (если не заключено в скобки), поскольку запятая на верхнем уровне будет интерпретирована как начало следующего декларатора.
При инициализации объектов типа с плавающей запятой все вычисления для объектов с автоматической длительностью хранения выполняются как бы во время выполнения и подвержены влиянию текущего округления ; ошибки чисел с плавающей запятой регистрируются в соответствии с math_errhandling . Для объектов со статической и thread-local длительностью хранения вычисления выполняются как бы во время компиляции, и исключения не возникают:
void f(void) { #pragma STDC FENV_ACCESS ON static float v = 1.1e75; // не вызывает исключений: статическая инициализация float u[] = { 1.1e75 }; // вызывает FE_INEXACT float w = 1.1e75; // вызывает FE_INEXACT double x = 1.1e75; // может вызвать FE_INEXACT (зависит от FLT_EVAL_METHOD) float y = 1.1e75f; // может вызвать FE_INEXACT (зависит от FLT_EVAL_METHOD) long double z = 1.1e75; // не вызывает исключений (преобразование точное) }
Пример
#include <stdbool.h> int main(void) { bool b = true; const double d = 3.14; int k = 3.15; // преобразование из double в int int n = {12}, // необязательные фигурные скобки *p = &n, // неконстантное выражение допустимо для автоматической переменной (*fp)(void) = main; enum {RED, BLUE} e = RED; // перечисления также являются скалярными типами }
Ссылки
- Стандарт 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 Инициализация