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

为何constexpr中超出作用域变量的地址等于零?

constexpr函数中栈变量地址编译期求值的特殊处理

为什么这段代码能编译通过?

C++20扩展了constexpr函数的能力,允许在constexpr函数内获取自动变量(栈变量)的地址,但有个关键前提:只要不对这个地址进行解引用操作,编译期求值就是合法的。

你的代码里:

constexpr auto foo()
{
    int x = 5;    
    return &x;
}

static_assert(foo() == 0);

当foo()在编译期上下文(比如static_assert)中被调用时,编译器不会为x分配实际的栈内存。此时返回的地址是一个编译期占位值,GCC选择用0来表示这个无实际意义的地址——这完全符合C++标准的规则,标准允许编译器将这类未绑定到实际存储的指针映射为任意值,只要程序没有通过该指针访问内存。

必须注意的风险

如果尝试在运行期调用foo()并解引用返回的指针,会触发未定义行为:

int main() {
    int* p = foo();
    *p = 10; // 严重错误:运行期x已销毁,指针悬空;编译期返回的地址也无对应内存
}

只有在constexpr函数内部、同一个求值上下文里解引用这个地址才是合法的,比如:

constexpr int bar() {
    int x = 5;
    return *&x; // 合法,编译期直接返回5
}

标准规则简述

C++20标准明确,constexpr求值过程中获取自动变量的地址是允许的,但该指针的有效范围仅限于当前constexpr求值过程内部。如果将其传出到编译期求值上下文之外,编译器可以将其视为一个“无效占位指针”,只要程序不对其进行内存访问操作,代码就是合法的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:13