Namespaces
Variants

Constant expressions

From cppreference.net

多种表达式类型被称为 常量表达式

目录

预处理器常量表达式

#if #elif 之后的表达式必须展开为

字符常量在 #if 表达式中求值时,可能被解释为源字符集、执行字符集或其他实现定义的字符集。

#if 表达式中的整数算术运算采用 intmax_t 的语义处理有符号类型,采用 uintmax_t 的语义处理无符号类型。

(C99起)

整型常量表达式

整数常量表达式是由仅包含以下内容组成的表达式:

  • _Alignof (C23前) alignas (C23起) 运算符
(C11起)
  • 属于整数类型或属于算术类型且为强制转换的直接操作数的命名及复合字面常量
(since C23)

整数常量表达式在编译时进行求值。以下上下文要求被称为 整数常量表达式 的表达式:

(since C99)
(since C11)
  • 位精确整数类型( _BitInt ( N ) )的位数 N
(since C23)

静态初始化器

用于具有静态和线程局部 存储期 对象 初始化器 中的表达式 或使用 constexpr 存储类说明符声明的表达式 (C23起) ,必须是字符串字面量或满足以下条件之一的表达式:

1) 算术常量表达式 ,即由以下元素组成的任意算术类型的表达式:
(C11 起)
  • 算术类型的命名或复合字面常量
(C23 起)
2) 空指针常量(例如 NULL )。
3) 地址常量表达式 ,即
  • 空指针
  • 指向具有静态 存储期 对象的 左值 或函数指示符,通过以下方式转换为指针:
  • 使用一元取地址运算符
  • 将整型常量强制转换为指针
  • 通过数组到指针或函数到指针的隐式 转换
4) 某个完整对象类型的 地址常量表达式 ,加上或减去一个 整型常量表达式
5) 一个 命名常量 ,即满足以下条件的标识符:
  • 枚举常量
  • 预定义常量( true false nullptr 之一)
  • 使用存储类说明符 constexpr 声明且具有对象类型
或对结构体/联合类型的命名常量(可递归应用)应用 . 成员访问运算符的后缀表达式。
6) 一个 复合字面量常量 ,即:
  • 使用存储类说明符 constexpr 复合字面量
  • 对结构体/联合类型的复合字面量常量(可递归应用)应用 . 成员访问运算符的后缀表达式

结构体/联合常量 分别是具有结构体/联合类型的命名常量或复合字面量常量。若成员访问运算符 . 访问联合常量的成员,则被访问成员必须与该联合常量初始化器初始化的成员相同。

(C23 起)
7) 实现所接受的其他形式之一的常量表达式。

与整型常量表达式不同,静态初始化表达式不要求在编译时求值;编译器有权将此类初始化器转换为在程序启动前调用的可执行代码。

static int i = 2 || 1 / 0; // 将 i 初始化为值 1

浮点静态初始化表达式的值精度绝不会低于运行时执行同一表达式的值,但可能更高。

浮点常量表达式

不在静态初始化器中使用的浮点类型算术常量表达式始终如同在运行时求值,并受 当前舍入方向 影响(若 FENV_ACCESS 处于开启状态),且错误报告遵循 math_errhandling 的规定。

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float x = 0.0 / 0.0; // 静态初始化器:不会引发异常
    float w[] = { 0.0 / 0.0 };  // 引发异常
    float y = 0.0 / 0.0;        // 引发异常
    double z = 0.0 / 0.0;       // 引发异常
}

注释

如果表达式求值结果无法由其类型表示,则不能用作常量表达式。

实现可以接受其他形式的常量表达式。但这些常量表达式不被视为整型常量表达式、算术常量表达式或地址常量表达式,因此不能用于需要这些类型常量表达式的上下文。例如, int arr [ ( int ) + 1.0 ] ; 声明了一个可变长度数组。

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • 6.6 常量表达式 (p: 95-96)
  • C17 标准 (ISO/IEC 9899:2018):
  • 6.6 常量表达式 (p: 76-77)
  • C11 标准 (ISO/IEC 9899:2011):
  • 6.6 常量表达式 (p: 106-107)
  • C99标准(ISO/IEC 9899:1999):
  • 6.6 常量表达式(页码:95-96)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.4 常量表达式

另请参阅

C++ 文档 关于 常量表达式