如何让 gcc/clang 警告 switch 语句中缺少的中断

问题描述 投票:0回答:3

有没有办法让

gcc
clang
警告 switch 语句中缺少中断?

具体来说,我几乎总是希望 case 语句以中断结尾,如果我不这样做的话,如果我能让编译器抱怨,那就太好了。更好的是如果它会寻找一个break语句或一个“//失败”评论。

人们是否有不同的解决方案来帮助自己不把事情搞砸?

gcc coding-style switch-statement clang gcc-warning
3个回答
13
投票

对于 Clang trunk,请使用

-Wimplicit-fallthrough
。如果您使用的是 C++11,可以使用
[[clang::fallthrough]];
语句来标记故意失败(有关更多信息,请参阅此属性的 文档)。该警告(尚未)检查“失败”评论。此功能不会出现在即将发布的 Clang 3.1 版本中,但它(可能!)会出现在 3.2 中。

编辑: Clang 的属性现在是 C++17 的一部分,名称为

[[fallthrough]];


3
投票

警告

-Wimplicit-fallthrough
已在GCC 7中实现。(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7652)

该选项的默认“级别”是 3。这意味着什么可以在 GCC 文档中进行解释(https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wimplicit-fallthrough )或功能实现者的博客中 (https://developers.redhat.com/blog/2017/03/10/wimplicit-fallthrough-in-gcc-7)。

除了标记失败的神奇注释之外,在 C23 中还有一个与 C++17 属性兼容的

[[fallthrough]]
属性。在之前的版本中,使用魔术注释或非标准(GCC/Clang 特定)
 __attribute__ ((fallthrough))
。如果您还需要支持 MSVC,请将其包装在宏中。

这是执行兼容宏的一种方法。在宏名称中使用您项目的前缀(而不是我选择的

PN
)。

// fallthrough
#if defined __cplusplus && defined __has_cpp_attribute
    #if __has_cpp_attribute(fallthrough) && __cplusplus >= __has_cpp_attribute(fallthrough)
        #define PN_FALLTHROUGH [[fallthrough]]
    #endif
#elif defined __STDC_VERSION__ && defined __has_c_attribute
    #if __has_c_attribute(fallthrough) && __STDC_VERSION__ >= __has_c_attribute(fallthrough)
        #define PN_FALLTHROUGH [[fallthrough]]
    #endif
#endif
#if !defined PN_FALLTHROUGH && defined __has_attribute
    #if __has_attribute(__fallthrough__)
        #define PN_FALLTHROUGH __attribute__((__fallthrough__))
    #endif
#endif
#if !defined PN_FALLTHROUGH
    #define PN_FALLTHROUGH (void)0
#endif

(来自 https://github.com/apache/qpid-proton/blob/001195c05a5fa1ec3d3b14a4963b82556450819f/c/include/proton/annotations.h#L93-L110


2
投票

您问如果它会查找中断语句或“//失败”注释,那就太好了。

还记得 Henry Spencer 的第一条 C 程序员十诫吗?

1。你应该经常运行 lint

看起来你需要的是 PC-Lint / flexelint。这是警告 616:

616 控制流进入 case/default -- 流是可能的 控制落入 case 语句或 default 语句 多于。这是故意的还是程序员忘记插入一个 中断声明?如果这是故意的,请发表评论 紧接在标记为以下的语句之前:

case 'a': a = 0;
   /* fall through */
case 'b': a++;
© www.soinside.com 2019 - 2024. All rights reserved.