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

C++常量求值期间悬空指针是否可能与有效指针相等?

结论

GCC的实现不符合C++17标准要求,该比较操作的结果是标准明确规定的,既不属于未定义行为也不属于实现定义行为。

判定依据
  • C++标准对常量表达式求值有严格约束,所有不符合标准要求的操作都会直接导致常量求值失败,不存在运行期那种不确定的未定义行为。
  • 根据C++17 [expr.eq] 条款的规定:两个指针相等当且仅当它们满足以下任一条件:
    1. 都为空指针
    2. 指向同一个对象/函数
    3. 指向同一个数组的尾后位置
    4. 分别指向同一个完整对象的两个非静态成员子对象,且两个成员属于同一个公共基类子对象
  • 示例代码中,指针x指向的是第一次调用f()时创建的栈变量c,该对象在第一次调用结束后生命周期已经终结;指针p指向的是第二次调用f()时新创建的栈变量c,二者指向的是完全独立的两个对象,因此x == p的结果标准明确规定为false。
  • Clang的处理符合标准要求,它在常量求值过程中会追踪指针指向对象的生命周期和身份标识,不会仅根据地址数值判定指针相等。GCC的问题在于早期版本常量求值时没有完整追踪指针指向对象的身份,仅按地址数值做比较,把两次调用复用的相同栈地址判定为相等,才会触发throw导致static_assert失败。
示例代码
constexpr auto f(int * x = nullptr) {
    int c = 0;
    auto p = &c;
    if ( x == p )
        throw "unexpected";
    return p;
};

int main() {
    static_assert( f( f() ) );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:48:03