带引用参数的consteval函数嵌套调用时Clang报错是否为Bug?
结论
Clang的该报错行为属于编译器Bug,GCC的编译结果符合C++标准规定。
原因分析
涉及的测试代码如下:
template<class T> consteval auto foo(const T&) { return 0; } template<class T> consteval auto bar(const T& t) { auto n = foo(t); return n; } int main() { static_assert(foo("abc") == 0); static_assert(bar("abc") == 0); }
Clang的报错逻辑为:在bar中调用foo(t)时,参数t的值未知,无法用于常量表达式,因此判定consteval函数调用非法。
该判定不符合C++标准的核心原因有两点:
- 首先
foo函数的实现完全没有读取传入的参数值,返回值是固定的字面量0,整个调用过程不需要依赖任何参数的值即可计算出结果。 - 其次常量表达式规则中,仅将引用绑定到对象、不读取对象非常量值的操作,本身不会导致表达式失去常量属性。此处只是将
bar的参数引用传递给foo,全程没有读取引用指向的数组内容,完全满足常量表达式的要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

