You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C23标准中constexpr支持哪些新类型与操作?有何限制?

C23中constexpr支持的新类型、操作及限制

C23引入constexpr关键字,用于定义编译时常量,可替代传统枚举或宏来实现类型安全的编译期常量定义,示例如下:

constexpr int x = 10;
constexpr int y = x + 10; // 合法

switch (some_var) {
    case y: // 合法,y是编译时常量
        // ...
}
static int z = y; // 合法

相较于C标准此前仅支持整数常量、全局/static对象地址作为编译时常量,且仅能执行有限算术运算的限制,C23对constexpr的能力做了大幅扩展,具体如下:

支持的新类型与操作

新增支持的类型

  • 浮点类型:float、double、long double均可定义为constexpr对象,编译时即可完成浮点运算,例如:
    constexpr double pi = 3.1415926;
    constexpr double circle_area = pi * 5 * 5; // 编译时计算圆面积
    
  • 指针与数组:支持编译时指针算术、空指针比较,以及constexpr数组的元素访问、长度计算;还能在编译时初始化数组,例如:
    constexpr int arr[] = {1,2,3,4};
    constexpr int arr_len = sizeof(arr)/sizeof(arr[0]); // 编译时获取数组长度
    constexpr int* ptr = &arr[2]; // 编译时获取数组元素地址
    
  • 结构体/联合体:支持编译时初始化结构体,以及访问其成员(只要成员类型支持constexpr),例如:
    typedef struct {
        int x;
        double y;
    } Point;
    constexpr Point p = {10, 20.5};
    constexpr int px = p.x; // 编译时访问结构体成员
    

新增支持的操作

  • 编译时浮点算术运算:加减乘除、取模、幂运算等,只要运算结果无未定义行为
  • 编译时位运算:移位、与、或、非、异或等操作,扩展到更多支持的类型
  • 编译时安全类型转换:整数与浮点数之间的constexpr转换(无溢出等未定义行为时)
  • 调用自定义constexpr函数:只要函数内部操作均符合constexpr规则,即可在编译时执行
  • 结合if constexpr实现编译时分支逻辑:根据constexpr表达式的结果选择编译代码路径
  • 基于sizeof、alignof的复杂编译时计算:可将这些运算符的结果参与更复杂的constexpr表达式

核心限制

  • 所有constexpr表达式必须是编译时可确定的,不能依赖运行时变量(如用户输入、栈上非static变量)
  • 禁止出现未定义行为:比如除以零、数组越界、浮点溢出、访问局部非static对象的地址等
  • 指针类型的constexpr操作仅允许使用全局对象、static对象、字符串字面量的地址,不能获取局部非static对象的地址
  • 浮点类型的constexpr运算可能存在编译器实现差异:不同编译器的浮点精度处理可能导致结果略有不同
  • constexpr函数内不能包含goto、try-catch,也不能调用非constexpr函数
  • 联合体的constexpr操作仅能访问当前活跃的成员,否则属于未定义行为

内容的提问来源于stack exchange,提问作者CPlus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 01:13:28