C++常量求值时不同变量指针是否可相等?MSVC实现是否符合标准
结论
MSVC的该常量求值行为不符合C++标准规定,属于实现缺陷。指向不同自动存储期对象的指针在常量求值场景下不可能相等。
标准依据
- C++标准明确规定:两个指针相等当且仅当它们指向同一个对象/函数、同为空指针、或指向同一数组的尾后位置。
- 对于函数中的自动存储期局部变量,每一次函数调用都会产生独立的变量实例,每个实例都具有唯一的身份标识,对应的地址也必然互不相等,该规则在常量求值过程中同样生效。
示例代码行为分析
constexpr bool f(int * x = nullptr) { int c = 0; return x ? (x != &c) : f(&c); }; static_assert( f() ); //fails in MSVC
代码执行逻辑如下:
- 顶层调用
f()时,参数x为空指针,触发递归调用f(&c),此处传入的是顶层调用栈中局部变量c的地址。 - 进入第二层调用栈后,参数x为顶层
c的地址,当前栈又生成了一个独立的局部变量c,两个c是完全独立的不同对象。 - 此时判断
x != &c的结果必然为true,所以f()最终返回值为true,static_assert理应通过。
MSVC报错的原因是其在常量求值过程中错误地合并了不同调用栈下同名局部变量的地址,违反了标准对自动变量实例唯一性的要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

