©
This document usesPHP Chinese website manualRelease
几种表达式被称为常量表达式。
#if 或 #elif 后面的表达式必须扩展为。
除赋值,增量,减量,函数调用或逗号之外的其他操作符,其参数是预处理常量表达式
整数常量
字符常量
特殊的预处理器操作员defined
当在#if
表达式中计算字符常量时,可以在源字符集,执行字符集或其他一些实现定义的字符集中解释字符常量。
Integer arithmetic in #if-expressions is performed using the semantics of intmax_t for signed types and uintmax_t for unsigned types. |
(since C99) |
---|
一个整型常量表达式是表达式。
除赋值,递增,递减,函数调用或逗号以外的其他操作符,除了转换操作符只能将算术类型转换为整数类型
整数常量
枚举常量
字符常量
浮点型常量,但前提是它们立即用作转换为整数类型的操作数
操作数不是VLA的操作符的大小(自C99起)
_Alignof operators |
(since C11) |
---|
_Alignof operators
(since C11)
整数常量表达式在编译时进行评估。以下上下文需要称为整型常量表达式的表达式':
位字段的大小。
枚举常量的值
case
switch语句的标签
非VLA(自C99以来)阵列的大小
整数指针隐式转换。
The index in an array designator |
(since C99) |
---|
数组指示符中的索引
(since C99)
The first argument of _Static_assert The integer argument of _Alignas |
(since C11) |
---|
第一个论点_Static_assert
整数参数_Alignas
(since C11)
在具有 static 和 thread_local 存储持续时间的对象的初始化器中使用的表达式必须是可能是以下某个表达式的表达式。
1)算术常数表达式,它是由任意算术类型组成的表达式
除赋值,增量,减量,函数调用或逗号以外的其他操作符,除了转换操作符必须将算术类型转换为其他算术类型
整数常量
浮点常量
枚举常量
字符常量
操作数不是VLA的操作符的大小(自C99起)
_Alignof operators |
(since C11) |
---|
_Alignof 操作符
(since C11)
2)空指针常量NULL
3)地址常量表达式,这是
一个空指针
左值指定一个静态存储持续时间的对象或一个函数指示符,并转换为指针
通过使用一元地址运算符
通过将一个整型常量转换为一个指针
通过数组到指针或函数到指针的隐式转换
4)地址常量表达一些完整的对象类型,加或减一个整型常量表达式
与整型常量表达式不同,静态初始化表达式不需要在编译时进行评估; 编译器可以自由地将这些初始化程序转换为在程序启动之前调用的可执行代码。
static int i = 2 || 1 / 0; // initializes i to value 1
浮点静态初始化器的值永远不会比在运行时执行的相同表达式的值精确,但它可能会更好。
在静态初始化器中未使用的浮点类型的算术常量表达式总是在运行时期间评估为 - 如果受到当前四舍五入的影响(如果 FENV_ACCESS处于打开状态)并报告 math_errhandling 中指定的错误。
void f(void){#pragma STDC FENV_ACCESS ON static float x = 0.0/0.0; // static initializer: does not raise an exception float w[] = { 0.0/0.0 }; // raises an exception float y = 0.0/0.0; // raises an exception double z = 0.0/0.0; // raises an exception}
如果一个表达式的计算结果不能用它的类型表示,那么它就不能用作常量表达式。
C11 standard (ISO/IEC 9899:2011):
6.6 Constant expressions (p: 106-107)
C99 standard (ISO/IEC 9899:1999):
6.6 Constant expressions (p: 95-96)
C89/C90 standard (ISO/IEC 9899:1990):
3.4 CONSTANT EXPRESSIONS