gcc 错误:此语句可能无法通过[-Werror=implicit-fallthrough=]

ulydmbyx  于 2022-11-13  发布在  其他
关注(0)|答案(4)|浏览(531)

我试图编译mitk在ubuntu上,我得到了这个错误:
错误:此语句可能无法通过[-Werror=implicit-fallthrough=]
这里有一部分代码:

/** Get memory offset for a given image index */
      unsigned int GetOffset(const IndexType & idx) const
      {
       const unsigned int * imageDims = m_ImageDataItem->m_Dimensions;

        unsigned int offset = 0;
        switch(VDimension)
        {
        case 4:
         offset = offset + idx[3]*imageDims[0]*imageDims[1]*imageDims[2];
        case 3:
        offset = offset + idx[2]*imageDims[0]*imageDims[1];
        case 2:
        offset  = offset + idx[0] + idx[1]*imageDims[0];
         break;
        }

        return offset;
      }

如果您能提供帮助,我将不胜感激。

eivnm1vs

eivnm1vs1#

Switch case语句在默认情况下将失败。在所示程序的情况下,如果VDimension为4,则所有

offset = offset + idx[3]*imageDims[0]*imageDims[1]*imageDims[2];
offset = offset + idx[2]*imageDims[0]*imageDims[1];
offset  = offset + idx[0] + idx[1]*imageDims[0];

将被执行。
在其他一些语言中,如Pascal,只执行一个case,没有fallthrough的概念。因此,不熟悉C的程序员可能会无意中编写fallthrough开关。
如果是无意的,则需要在每个事例之间添加一个中断,以避免失败。
这句话可能会落空
这个警告会通知程式设计人员这个错误。这个警告选项可以用GCC编译器参数-Wimplicit-fallthrough来控制。它预设不会启用,也不会由-Wall来启用,但会由-Wextra来启用。
如果使用了-Werror开关,则警告将变为错误.默认情况下,-Werror未启用.
C
17引入了[[fallthrough]]属性,当它是有意的时候,可以用来显式地记录失败。如果使用了它,编译器不应该发出警告:

switch(VDimension)
        {
        case 4:
         offset = offset + idx[3]*imageDims[0]*imageDims[1]*imageDims[2];
         [[fallthrough]];
        case 3:
         offset = offset + idx[2]*imageDims[0]*imageDims[1];
         [[fallthrough]];
        case 2:
         offset = offset + idx[0] + idx[1]*imageDims[0];
         break;
        }

在C++17之前,GCC提供了一个语言扩展属性__attribute__ ((fallthrough))用于相同的目的。
也可以用注解来记录这个失败,Wimplicit-fallthrough可以根据开关使用的值来检测这样的注解。更多细节在GCC的文档中。

ctzwtxfj

ctzwtxfj2#

您应该在每个case语句中添加关键字break,如果不这样做,代码将从与条件匹配的case开始运行,并继续满足
破碎;
例如:如果VDimension = 4,则代码将从case 4 =〉继续运行到case 3 =〉康廷到case 2,然后中断。这意味着它将执行以下命令:

offset = offset + idx[3]*imageDims[0]*imageDims[1]*imageDims[2];
offset = offset + idx[2]*imageDims[0]*imageDims[1];
offset  = offset + idx[0] + idx[1]*imageDims[0];
break;
return offset;

我想你的代码应该是:

/** Get memory offset for a given image index */
  unsigned int GetOffset(const IndexType & idx) const
  {
   const unsigned int * imageDims = m_ImageDataItem->m_Dimensions;

    unsigned int offset = 0;
    switch(VDimension)
    {
    case 4:
     offset = offset + idx[3]*imageDims[0]*imageDims[1]*imageDims[2];
     break;
    case 3:
     offset = offset + idx[2]*imageDims[0]*imageDims[1];
     break;
    case 2:
     offset  = offset + idx[0] + idx[1]*imageDims[0];
     break;
    }

    return offset;
  }
5hcedyr0

5hcedyr03#

如果您完全确定这些警告是无关紧要的,请在编译过程中删除-Werror标志。
对于在配置阶段放置标记的项目,您可以
./configure --disable-werror
运行前
make

ctehm74n

ctehm74n4#

假设代码是正确的,如果可以的话,只需将-Wno-implicit-fallthrough添加到编译器标志中。
正如其他人所说的,当VDimension为4时,情况4、3和2的代码将按该顺序执行,因为没有break语句来停止它。如果这是预期的行为(我怀疑是),那么编译器会烦人地警告您switch语句正在做它应该做的事情。

相关问题