我试图在 ubuntu 上编译 mitk,但我得到了这个错误:
error:这个语句可能会通过 [-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;
}
如有任何帮助,我将不胜感激。
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,没有fall through的概念。因此,刚接触 C++ 的程序员可能会无意中编写 fall through switches。
如果掉线是无意的,您需要在每个案例之间添加一个中断以防止掉线。
这个声明可能落空
此警告通知程序员有关失败的信息。可以使用 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 文档中的更多详细信息。
您应该在每个 case 语句中添加关键字 break,如果您不这样做,代码将从匹配条件的 case 运行并继续满足
休息;
例如:如果 VDimension = 4,则代码将从案例 4 运行 => 继续到案例 3 => 继续到案例 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;
}
如果您绝对确定警告无关紧要,请在编译期间删除
-Werror
标志。
对于在配置阶段放置标志的项目,您可以这样做
./configure --disable-werror
跑步前
make
假设代码是正确的,如果可以的话,只需将
-Wno-implicit-fallthrough
添加到编译器标志。这在 Makefile 中通常是 CFLAGS
或 CXXFLAGS
。
正如其他人所说,当 VDimension 为 4 时,案例 4、3 和 2 的代码将按该顺序执行,因为没有
break
语句来阻止它。如果那是预期的行为(我怀疑是),那么编译器会烦人地警告你 switch 语句正在做它应该做的事情。
/** 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;
}
只需添加“中断;”完成任何案件后。