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

Using throw keyword in a function produces a warning with gcc

我需要找到一种方法(请使用 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(从未达到),因为它会使代码更难阅读。

在 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 是非 void 函数并且触发了错误,但函数 throw_invalid 需要该属性。将 throw_invalid 设置为 noreturn 将告诉编译器,每当采用带有函数 throw_invalid 的代码路径时,foo 也不会 return。

据我了解,在进行任何计算之前,您首先需要确保您的参数有效。话虽如此,我相信您只需相应地重写代码就可以解决这个问题

在你的例子中,是这样的:

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

   return 42;
}

对于 GCC,您可以将 noreturn 属性添加到方法中:

void throw_invalid()
#ifdef __GNUC__
    __attribute__ ((noreturn))
#else
    // something here for Visual Studio
#endif
{
  throw std::invalid_argument( "invalid" );
}

手册说:

The noreturn keyword tells the compiler to assume that 'fatal' cannot return. It can then optimize without regard to what would happen if the function ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables.

The noreturn keyword does not affect the exceptional path when that applies: a noreturn-marked function may still return to the caller by throwing an exception or calling longjmp.

我对你的其他编译器没有经验,所以无法填补那里的空白;对不起。