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

静态变量地址可作为constexpr使用的行为是否为C++标准强制要求?

静态变量地址可作为constexpr使用的行为是否为C++标准强制要求?

没错,这个行为确实是C++标准强制要求的,咱们一步步拆解你遇到的几种情况,就能明白标准的规则:

  • 为什么第一个例子无法编译?
    看这段代码:

    int main() {
        constexpr int i = 0;
        constexpr const int* ptr = &i;
    }
    

    这里的i是非静态的局部变量,哪怕它被标记为constexpr,它的存储空间还是在main函数的栈帧里。C++标准明确规定:非静态局部对象的地址不能作为编译期常量表达式——虽然这个例子里编译器理论上能"猜"出地址,但标准不允许这种情况,因为栈帧的位置本质上是程序运行时才会分配的,没有固定的编译期地址。

  • 为什么全局constexpr变量的地址可以用在constexpr里?
    这段能编译的代码:

    constexpr int i = 0;
    int main() {
        constexpr const int* r = &i;
    }
    

    这里的i是全局变量,它存在于程序的静态存储区,它的地址在编译阶段就已经被确定下来了,完全符合constexpr对编译期常量的要求,所以标准允许把它的地址用来初始化constexpr指针。

  • 为什么静态局部constexpr变量也可以?
    再看这段代码:

    int main() {
        static constexpr int i = 0;
        constexpr const int* r = &i;
    }
    

    静态局部变量i的存储空间同样在静态存储区,和全局变量一样,它的地址在编译时就能被确定,所以标准也允许把它的地址作为constexpr值来使用。

总结一下:C++标准对常量表达式的定义里,明确将静态存储期对象的地址(包括指向这类对象的指针操作)纳入了合法范围,而非静态局部对象的地址则被排除在外,所以你遇到的这些编译结果都是标准强制要求的,不是某个编译器的特殊行为。

备注:内容来源于stack exchange,提问作者dwto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 11:03:02