"if constexpr"与"try in constexpr function"警告的交互
"if constexpr" interaction with "try in constexpr function" warning
我声称这个程序应该是格式良好的:它声明了S<int>
的constexpr成员函数。然而,GCC和Clang都拒绝这一计划。
template<class T>
struct S {
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
try {} catch (...) {}
return 1;
}
}
};
int main()
{
S<int> s;
return s.foo(); // expect "return 0"
}
GCC表示:
错误:"constexpr"函数中的"try">
Clang说:
错误:constexpr函数中不允许使用语句
他们似乎都没有注意到"try"语句位于if constexpr
语句的丢弃分支中。
如果我将try
/catch
分解为非constexpr成员函数void trycatch()
,那么Clang和GCC都对代码感到满意,尽管它的行为应该相当于不满意的版本。
template<class T>
struct S {
void trycatch() {
try {} catch (...) {}
}
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
trycatch(); // This is fine.
return 1;
}
}
};
这是吗
- GCC和Clang都有错误吗
- GCC和Clang正在忠实执行的标准中的缺陷
- 由于
foo()
的"条件常数"导致的实施质量问题
(无关背景:我正在为any
的分配器感知版本实现constexprany::emplace<T>()
,该版本的分配器可能是constexpr-per-P0639(即,它可能缺少deallocate
成员函数),也可能不是。在前一种情况下,我们不想要或不需要try
;在后一种情况下,如果T
的构造函数抛出,我们需要try
来调用deallocate
。)
编译器遵守标准。C++17草案N4659说([dcl.constexpr]/(3.4.4)):
constexpr函数的定义应满足以下要求:
。。。
其函数体应为
= delete
、= default
或不包含的复合语句
。。。
试块,或
。。。
并且对于";丢弃的语句";例如CCD_ 17中的CCD_。关于丢弃语句,唯一指定的特殊之处是,丢弃语句没有实例化,丢弃语句中的odr使用不会导致需要对所用声明进行定义,并且在确定具有占位符返回类型的函数的真实返回类型时,会忽略丢弃的return
语句。
我没有看到任何现有的C++问题在讨论这一点,并且提出if constexpr
的论文P0292R1没有涉及与constexpr函数的交互。
- 警告处理为错误这里有什么问题
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- cppcheck在const std::string[]上引发警告
- Visual C++ constexpr Hints
- GCC对可能有效的代码抛出init list生存期警告
- 如何在BST的这个简单递归实现中消除警告
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 关于std::move的使用,是否有编译警告
- 在非constexpr函数上添加的constexpr限定符不会触发任何警告
- 如何使我的C 编译器发出constexpr值(例如警告?)
- 关于静态模板化 constexpr 的 Clang 警告(未定义内联函数)
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- "if constexpr"与"try in constexpr function"警告的交互
- ConstexPR静态模板功能:G 错误是Clang上的警告
- constexpr 返回数组,GCC 警告
- 如何使用未使用的宏在CONSTEXPR函数中沉默警告