错误:此语句可能会失败 [-Werror=implicit-fallthrough=]

aga*_*sim 11 c++ gcc build gcc-warning mitk

我正在尝试在 ubuntu 上编译 mitk,但出现此错误:

错误:此语句可能会失败 [-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;
      }
Run Code Online (Sandbox Code Playgroud)

请提供任何帮助,我将不胜感激。

小智 7

你应该在每个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;
Run Code Online (Sandbox Code Playgroud)

我认为你的代码应该是:

/** 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;
  }
Run Code Online (Sandbox Code Playgroud)

  • 是的,这将消除警告。但它可能会破坏代码,看起来它故意依赖于失败。 (7认同)

eer*_*ika 7

默认情况下,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];
Run Code Online (Sandbox Code Playgroud)

将被执行。

在其他一些语言中,例如Pascal,只执行一个case,没有fall through的概念。因此,刚接触 C++ 的程序员可能会无意中编写失败。

如果掉线是无意的,您需要在每个案例之间添加一个中断,以免掉线。

此声明可能会失败

此警告通知程序员有关失败的信息。这个警告选项可以通过 GCC 编译器开关来控制-Wimplicit-fallthrough。它默认不启用-Wall,也不是由启用,但由 启用-Wextra

如果使用-Werror开关,警告会变成错误。-Werror默认情况下不启用。

C++17 引入了[[fallthrough]]属性,可用于明确记录有意的失败。如果使用它,编译器不应发出警告。

在 C++17 之前,GCC 为__attribute__ ((fallthrough))相同的目的提供了语言扩展属性。

失败也可以用注释记录,并且Wimplicit-fallthrough可以根据开关使用的值检测到这样的注释。GCC 文档中的更多详细信息。

  • 指向 Fallthrough 属性的链接或使用它的示例会很有帮助。 (3认同)