提问人:mgNobody 提问时间:9/2/2023 最后编辑:mgNobody 更新时间:9/2/2023 访问量:107
C++ 中的 constexpr switch 语句 [复制]
constexpr switch statements in C++ [duplicate]
问:
我们有C++支持吗?switch constexpr
对于上下文,我们都知道我们有编译时 if 语句。这些 if 语句的开销非常低,因为编译器将在编译时评估它们。我们(或者特别是我)在进行模板专业化时会使用它们。if constexpr
我想知道我们是否有同样的东西。我有兴趣使用 switch 语句而不是具有相同运行时开销的长列表。switch
if constexpr
例:
考虑以下代码:
template <int OP>
int mul(int in) {
if constexpr (OP == 1) {
return in * 2;
} else if constexpr (OP == 2) {
return in * 3;
} else {
return in * 4;
}
}
以下代码在编译方面是否等同于上述代码?
template <int OP>
int mul(int in) {
switch(OP) {
case 1:
return in * 2;
case 2:
return in * 3;
default:
return in * 4;
}
}
这是指向上述示例链接的 Godbolt 链接。不知何故,该链接确认了我上面写的内容是等效的(就最终编译工件而言)。但是,我仍然对C++规范的正式确认感兴趣。
答:
以下代码在编译方面是否等同于上述代码?
代码具有完全相同的可观察行为。您只需要(或不存在的等效项)以允许未采用的分支包含如果使用模板专用化的模板参数实例化的代码,这些代码的格式不正确。if constexpr
switch
任何关于优化或最终使用什么机器指令来实现指定的可观察行为的事情都取决于编译器,并且不会为任何一个版本指定。语言标准正式地只指定了编译器需要确保的程序的格式良好和允许的可观察行为,仅此而已。
因为甚至不会导致未获取分支的实例化,所以编译器当然可以确定不会为它发出任何指令,而在通常的情况下,您需要依靠优化来解决这个问题。但是,如果条件明显是编译时常量,那么编译器可能会发现其他分支是死代码,并将在足够高的优化级别删除它们。如果条件很复杂,并且不是明显的编译时常数,则情况可能会有所不同。if constexpr
switch
评论
if constexpr
switch
if constexpr
else if constexpr
else
你误解了什么是为了什么。它不是一个优化的推动者,因为你清楚地看到自己编译器会优化你的。if constexpr
if
相反,提供的是编写无效的 C++ 代码(可解析但格式不正确)的能力,这些代码仅在其自己的分支中有效(例如,如果您正在测试模板化类型),但总体上无效。if constexpr
评论
switch
以下代码在编译方面是否等同于上述代码?
在 gcc 中(即使在 7.1 等旧版本中,只要它支持模板),是的。
下面是测试代码。你可以发现编译器删除了所有的死分支,两个函数在汇编中是一样的。
评论