在函数中使用throw关键字会产生带有gcc的警告

时间:2015-12-03 12:44:15

标签: c++ gcc portability throw

我需要找到一种方法(请使用C ++ 03,不能使用C ++ 11)来删除gcc对以下(伪)代码产生的警告:

#include <stdexcept>

void throw_invalid()
{
  throw std::invalid_argument( "invalid" );
}

int foo(const char * str)
{
  if( str ) return 42;
  throw_invalid();
  // insert portable -fake- code that will get optimized away
}

我的代码需要至少在gcc 5.x(-Wall)和Visual Studio上发出警告。我的throw_invalid函数用于避免样板代码,并将异常集中在与无效参数相关的单个函数中。

目前警告是:

$ g++ -Wall -c foo.cxx 
b.cxx: In function ‘int foo(const char*)’:
b.cxx:13:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

我希望避免添加假return -1(从未到达),因为它会让代码更难阅读。

3 个答案:

答案 0 :(得分:6)

使用c ++ 11,您可以使用attribute specifier [[noreturn]]

像这样:

[[noreturn]] void throw_invalid()
{
     throw std::invalid_argument( "invalid" );
}

int foo(const char * str)
{
    if( str ) return 42;
    throw_invalid();
    // insert portable -fake- code that will get optimized away
}

<强>更新

就像Walter在评论中提到的那样,即使函数foo是非空函数而触发错误的函数,也就是需要该属性的函数throw_invalid。将throw_invalid设置为noreturn将告诉编译器,只要采用具有函数foo的代码路径,throw_invalid也不会返回。

答案 1 :(得分:3)

根据我的理解,在进行任何计算之前,首先需要确保参数有效。说,我相信你可以通过相应地重写你的代码来克服这个问题

在你的例子中,类似的东西:

int foo(const char * str)
{
   // Make sure that str is valid
   if( str == NULL ) throw_invalid();

   return 42;
}

答案 2 :(得分:1)

对于GCC,您可以将void throw_invalid() #ifdef __GNUC__ __attribute__ ((noreturn)) #else // something here for Visual Studio #endif { throw std::invalid_argument( "invalid" ); } attrubute添加到方法中:

noreturn

手册说:

  

noreturn关键字告诉编译器假设&#39;致命&#39;   不能回来。然后它可以优化而不考虑什么   如果函数曾经返回,就会发生。这使得代码略胜一筹。   更重要的是,它有助于避免未初始化的虚假警告   变量

     

noreturn关键字不会影响特殊路径   适用:longjmp - 标记的功能仍可返回   通过抛出异常或致电alasql('SELECT * into html("#res") from xlsx("excel.xlsx")');来调用。

我没有你的其他编译器的经验,因此无法填补那里的差距;遗憾。

相关问题