【问题标题】:Is it possible to remove control flow statements with if constexpr? [duplicate]是否可以使用 if constexpr 删除控制流语句? [复制]
【发布时间】:2020-02-21 18:13:46
【问题描述】:

我正在测试if constexpr 的可能性,我想知道是否可以用它删除控制流语句。

我正在测试的代码是:

int main() {
    void *indirect_label;
    if constexpr (false) {
       goto label; // Rejected by MSVC, clang and GCC
    }
    if constexpr (false) {
        continue;  // Rejected by clang and GCC
    }
    if constexpr (false) {
        break; // Rejected by clang and GCC
    }
    if constexpr (false) {
        goto *indirect_label; // Rejected by clang and MSVC
    }
    return 1;
}

我为 GCC 和 clang 实现的间接 goto 语言扩展添加了一个测试。

考虑到如果条件为假,if constexpr 应该丢弃语句,为什么 MSVC 和 GCC 接受代码的某些部分(但不同)而 clang 拒绝所有四个。

什么行为是正确的?

【问题讨论】:

  • 坐下来等待有人完全错过问题的重点并开始为gotos 发疯。
  • 请注意if constexpr 用于模板。如果代码不依赖,则仍会编译正文:stackoverflow.com/questions/59393908/…
  • 这些控制语句在使用它们的上下文中没有任何意义。您不能在这些点使用continue;break;,并且label 不存在。间接 goto 不是标准 C++。
  • 如果您能向我们展示您想要达到的目标,我们或许可以帮助您。
  • @NicolasBértolo:这甚至比不上if constexpr 的幂。函数相互隔离,if constexpr 没有任何改变。

标签: c++ c++17 c++20


【解决方案1】:

if constexpr 不是宏。实际上,它仅在特定情况中获得与常规if 语句不同的功能,即在模板中以及条件本身基于模板参数。即便如此,被丢弃的语句至少必须具有潜在的合法性。

【讨论】:

  • 潜在合法”究竟应该理解什么?
  • @Fureeish:丢弃语句的规则非常复杂,最好在单独的问题中处理。它的要点基本上是“忽略模板是否可以用这些参数实例化的问题;如果所有这些都解决了,它仍然是合法的 C++ 吗?” goto label_that_doesnt_exist 绝对不会成为合法的 C++。 continuebreak 在不允许的地方也是如此。
  • 那么它在循环外接受breakcontinue 是MSVC 中的一个错误吗?
  • 另外,break; 语句仅在循环内部和switch 语句中有效。 continue; 语句仅在循环内有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 2023-04-09
  • 1970-01-01
  • 2017-05-15
  • 2021-09-08
  • 1970-01-01
  • 2019-10-28
相关资源
最近更新 更多