标量初始化

来自cppreference.com
< c‎ | language

初始化标量类型对象时,初始化器必须是单个表达式。

标量(包含布尔和枚举类型的整数类型,包含复数和虚数的浮点类型,以及包含指向函数指针的指针类型对象)的初始化器必须是单个表达式,可选地以花括号环绕:

= 表达式 (1)
= { 表达式 } (2)
= { } (3) (C23 起)
1,2) 求值该表达式,而其值在如同赋值般转换到对象类型后,成为被初始化对象的初值。
3) 空初始化对象,即对于算术或枚举类型对象初始化为数值零,或对指针类型对象初始化为空指针值。

注解

因为应用到转换到规则如同赋值,在确定 表达式 所转换到的类型时,忽略被声明类型上的 constvolatile 限定符。

不使用初始化器时应用的规则见初始化

同所有其他初始化,在初始化静态或线程局域存储期的对象时, 表达式 必须为常量表达式

表达式 不能为逗号运算符(除非加括号),因为顶层的逗号会被转译为下个声明器的开始。

在初始化浮点类型对象时,对所有拥有自动存储期的对象所作的计算如同在执行时进行,并受当前舍入影响;报告 math_errhandling 中指定的浮点错误。对于拥有静态和线程局域存储期的对象,计算如同在编译时进行,而且不引发异常:

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,   // 对自动对象,非常量表达式 OK
       (*fp)(void) = main;
    enum {RED, BLUE} e = RED; // 枚举亦是标量类型
}

引用

  • C17 标准(ISO/IEC 9899:2018):
  • 6.7.9/11 Initialization (第 101 页)
  • C11 标准(ISO/IEC 9899:2011):
  • 6.7.9/11 Initialization (第 140 页)
  • C99 标准(ISO/IEC 9899:1999):
  • 6.7.8/11 Initialization (第 126 页)
  • C89/C90 标准(ISO/IEC 9899:1990):
  • 6.5.7 Initialization