![](/img/trans.png)
[英]Why and how does GCC compile a function with a missing return statement?
[英]Why isn't GCC smart enough to understand a missing return statement?
我有这个C代码:
EaglePage* EaglePage_RealCopy(EaglePage *page)
{
if(NULL == page) {
return NULL;
}
switch(page->type) {
case EagleDataTypeUnknown:
EagleLogger_Log(EagleLoggerSeverityError, "Cannot page of Unknown type.");
return NULL;
case EagleDataTypeInteger:
return EaglePage_RealCopyInt_(page);
case EagleDataTypeVarchar:
return EaglePage_RealCopyVarchar_(page);
case EagleDataTypeFloat:
return EaglePage_RealCopyFloat_(page);
}
}
当我使用clang在Mac OS X上编译它时,它理解交换机处理所有“可能的”分支并且不会警告缺少返回语句(如Java)。 但是,如果我通过GCC 4.4.5运行相同的代码,它总是会给出一个丢失的返回警告。
这很烦人,因为如果我输入了返回语句,那么我的代码覆盖率会因为我没有涵盖那些“不可能”的情况而中断。 有没有办法让GCC像clang / javac一样处理这个问题?
这有时会发生,但使用default
标签很容易修复。
switch(page->type) {
case EagleDataTypeInteger:
return EaglePage_RealCopyInt_(page);
case EagleDataTypeVarchar:
return EaglePage_RealCopyVarchar_(page);
case EagleDataTypeFloat:
return EaglePage_RealCopyFloat_(page);
case EagleDataTypeUnknown:
default:
EagleLogger_Log(EagleLoggerSeverityError, "Cannot page of Unknown type.");
return NULL;
}
clang不仅仅是一个编译器,而是一个字节码编译器和静态分析工具的混合体。 因此,在这种特殊情况下,您没有看到来自clang的警告的原因是,可以证明您的函数不能使用交换机未涵盖的值进行调用。
或者它可能是铿锵声中的一个错误。
尝试将此函数添加到您的代码中,并确保调用它,看看会发生什么:
void BogusEaglePage_Call(void) {
EaglePage *bp, *br;
bp = malloc (sizeof (*bp));
if (bp) {
bp->type = (EagleDataTypeInteger | EagleDataTypeVarchar | EagleDataTypeFloat | EagleDataTypeUnknown) << 2;
br = EaglePage_RealCopy(bp);
}
}
如果clang仍然没有给你一个警告,我建议你报告一个缺陷。
你没有给编译器任何信息知道只有四个可能的值,例如你把switch(page-> type&3)然后编译器要足够智能知道你已经涵盖所有可能的处理案例和所有路径(交换机被标记为无法访问后的任何代码)。 编译器是否可以执行此操作与编译器,该品牌和版本的特定功能有关。
拥有一个单一的返回点并不能为你带来任何你想要做的事情,你仍然必须通过这个代码验证5条路径(你从系统层面说的是哪一条是不能到达那里)。 编译器总是不能始终查看系统级别,但有时只能关注功能级别。 llvm工具可以使用单独编译的源文件轻松地在整个项目中进行优化,其中gcc需要在一个大文件(包括include)中完成所有这些操作。
在编写代码时,编译器将正确生成代码中的第五条路径,即代码告诉它要执行的操作,除非编译器中存在错误,否则它将执行此操作。 如果您希望编译器执行其他操作,请通过更改源代码来告诉编译器执行其他操作(或者显示编译器比您向我们展示的更多,如果此处有代码,我们无法看到使用此代码编译另一个故事,或者如上所示,如果在此代码中您向编译器演示了范围限制,那么它可以有机会限制到该范围)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.