C23 的 constexpr 中可以发生哪些新类型和操作?

问题描述 投票:0回答:1

C23 添加了关键字

constexpr
,可用于将对象定义为编译时常量,而不是枚举或宏。例如:

constexpr int x = 10;
constexpr int y = x+10; // Valid

switch (some_var) {
    case y: // Valid
        // ...
}
static int z = y; // Valid

以前只有整数常量(

sizeof()
enum
或文字值,例如
10
)或全局/
static
对象的地址可以被视为编译/翻译时常量,并且可以执行一些算术运算在编译时对它们进行处理。

C23 中的

constexpr
表达式中是否可以处理任何新的操作和类型?有什么限制?

c constexpr compile-time-constant c23
1个回答
0
投票

复合文字

constexpr
可用于限定复合文字:

带有存储类说明符 constexpr 的复合文字是复合文字常量。复合文字常量是具有未命名对象的类型和值的常量表达式。

在 C23 之前,不支持编译时常量(甚至

static
)复合文字,即使它们的所有成员都是编译时常量:

static int x = (int){0}; // Non-portable
static int x = (constexpr int){0}; // Valid C23

struct
union

从结构体或联合常量开始,成员访问

.
运算符可用于形成命名常量 [...]。

constexpr
可以与
struct
union
组合来创建编译时常量对象。可以在编译时读取成员:

constexpr struct { int x; } s = {10}; static int x = s.x; // Valid
这不允许

编译时类型双关

如果成员访问运算符

.

访问联合常量的成员,则访问的成员应与联合常量的初始值设定项初始化的成员相同。

数组

无法在编译时访问任何数组成员的值:

数组下标

[]

 和成员访问 
->
 运算符、地址 
&
 和间接 
*
 一元运算符以及指针强制转换可用于创建地址常量,但对象的值不得使用这些运算符进行访问。

但是这些运算符

可以用于生成数组成员之一的地址作为编译时常量。

功能

C++ 风格

constexpr

 函数
不支持。因此,在 constexpr
 表达式中不能使用函数调用。

不支持的操作

常量表达式不得包含赋值、递增、递减、函数调用或逗号运算符,除非它们包含在未计算的子表达式中。

© www.soinside.com 2019 - 2024. All rights reserved.