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

为何consteval版RNG总是返回零?咨询C++标准对应条款

C++ consteval函数返回空指针的标准依据

在C++中,有一种实现随机数生成器(RNG)的方式是返回局部变量的地址:

void const* rng() noexcept { char c; return &c; }

这里利用每次函数调用时局部变量栈地址不同的特性,生成“随机”地址。

但尝试将其改为consteval变体时:

template <auto C> constexpr auto c() noexcept { return C; }
consteval void const* rng() noexcept { char c; return &c; }

函数始终返回空指针。这种行为的依据可以在C++标准的常量表达式规则中找到:

核心标准条款依据

根据C标准的§7.7(常量表达式)章节(以C20为例):

  • 常量表达式中,不能引用自动存储期对象的地址,除非该对象是用constexpr声明且具备常量初始化,或是满足特定条件的临时对象。而consteval函数要求整个函数的求值结果必须是合法的常量表达式。

上述consteval版本的rng函数中,char c是函数内的局部自动变量,它的地址无法构成合法的常量表达式。编译器遇到这种违规情况时,会将该地址视为无效值,最终表现为返回空指针。

可编译变体的合理性

编辑2中的代码在Clang中可以正常编译:

template <auto C> constexpr auto c() noexcept { return C; }
consteval auto rng1() noexcept { return &c<1>;}
consteval auto rng2() noexcept { return &c<2>;}

原因是&c<1>获取的是模板函数实例化后的函数地址,而函数属于静态存储期实体,其地址是合法的常量表达式,符合标准中对常量表达式允许引用静态存储期实体地址的规定,因此可以在consteval函数中返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:40:08