gpt4 book ai didi

C++ 强制编译时错误/警告开关中的隐式失败

转载 作者:IT老高 更新时间:2023-10-28 13:58:51 30 4
gpt4 key购买 nike

switch 语句非常有用,但会导致程序员忘记 break 语句的常见错误:

switch(val) {
case 0:
foo();
break;
case 1:
bar();
// oops
case 2:
baz();
break;
default:
roomba();
}

您显然不会收到警告,因为有时明确需要失败。好的编码风格建议在你故意失败时发表评论,但有时这还不够。

我很确定这个问题的答案是否定的,但是:目前(或将来提出)有什么方法可以要求编译器抛出错误(或至少是警告!)如果您的 case 没有至少一个 break; 或影响 //fallthru 的东西?有一个使用 switch 语句的防御性编程选项会很好。

最佳答案

嗯,clang 有 -Wimplicit-fallthrough,我不知道但使用 -Weverything 发现了它。所以对于这段代码,它给了我以下警告( see it live ):

warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
case 2:
^
note: insert '[[clang::fallthrough]];' to silence this warning
case 2:
^
[[clang::fallthrough]];
note: insert 'break;' to avoid fall-through
case 2:
^
break;

我能找到的关于这个标志的唯一文档是 Attribute Reference其中说:

The clang::fallthrough attribute is used along with the -Wimplicit-fallthrough argument to annotate intentional fall-through between switch labels. It can only be applied to a null statement placed at a point of execution between any statement and the next switch label. It is common to mark these places with a specific comment, but this attribute is meant to replace comments with a more strict annotation, which can be checked by the compiler.

并提供了一个如何标记显式失败的示例:

case 44:  // warning: unannotated fall-through
g();
[[clang::fallthrough]];
case 55: // no warning

attribute 的这种用法标记显式失败具有不可移植的缺点。 Visual Studio 生成错误,gcc 生成以下警告:

warning: attributes at the beginning of statement are ignored [-Wattributes]

如果你想使用-Werror,这是一个问题。

我用 gcc 4.9 试过这个,看起来 gcc 不支持这个警告:

error: unrecognized command line option '-Wimplicit-fallthrough'

截至 GCC 7 , -Wimplicit-fallthrough 受支持,并且 __attribute__((fallthrough)) 可用于在有意放弃时抑制警告。 GCC 确实在某些情况下识别“失败”注释,但可能会混淆 fairly easily .

我没有看到为 Visual Studio 生成此类警告的方法。

注意,Chandler Carruth说明 -Weverything 不用于生产用途:

This is an insane group that literally enables every warning in Clang. Don't use this on your code. It is intended strictly for Clang developers or for exploring what warnings exist.

但它对于找出存在哪些警告很有用。

C++17 变化

在 C++17 中,我们得到 [dcl.attr.fallthrough]p1 中涵盖的属性 [[fallthrough]] :

The attribute-token fallthrough may be applied to a null statement (9.2); such a statement is a fallthrough statement. The attribute-token fallthrough shall appear at most once in each attribute-list and no attributeargument- clause shall be present. A fallthrough statement may only appear within an enclosing switch statement (9.4.2). The next statement that would be executed after a fallthrough statement shall be a labeled statement whose label is a case label or default label for the same switch statement. The program is ill-formed if there is no such statement.

...

[ Example:
void f(int n) {
void g(), h(), i();
switch (n) {
case 1:
case 2:
g();
[[fallthrough]];
case 3: // warning on fallthrough discouraged
h();
case 4: // implementation may warn on fallthrough
i();
[[fallthrough]]; // ill-formed
}
}
—end example ]

live example using attribute .

关于C++ 强制编译时错误/警告开关中的隐式失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27965722/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com