2017-06-12 37 views
3

这是更便利的问题比什么的,但我想知道是否有什么办法可以抑制警告:抑制非平凡无用的警告“控制可以达到非void函数结束”

control may reach end of non-void function [-Wreturn-type]

对于其中我知道的代码没有问题的特定情况。我有我的代码库中一些辅助功能抛出异常,并为这样的代码:

int foo(int i) { 
    if (i > 10) { 
     return i*10; 
    } 
    else { 
     Exception::throwExcept(MyCustomException("Error: i not in the accepted range")); 
    } 
} 

我知道,它要么返回,或者抛出,不管是什么。因此,在我眼中,这个警告是毫无用处的,只是编译器无法确定控制流路径实际上最终会抛出。

我仍然希望看到这个警告弹出窗口的情况下,它实际上是一个代码是错误的(即没有返回或抛出的路径)的迹象。

这是可能的便携式方式?

编辑:忘了补充我使用的编译器,

Apple LLVM version 8.1.0 (clang-802.0.41)

+0

@Holt它不会改变任何东西,有或没有'else'。 – JBL

+0

如果您删除无意义的“else”,它还会发出警告吗? –

+1

'return Exception :: throwExcept(MyCustomException(“Error:i not in the accepted range”)),0'? – NathanOliver

回答

10

编译器无法弄清楚Exception::throwExcept()将不会返回。这里有两个解决方案。一个是告诉编译器,即

struct Exception 
{ 
    [[noreturn]] static void throwExcept(SomeType const&); 
}; 

(铛的-Wmissing-noreturn,其中包括在-Weverything,将发出警告,如果上面的函数可以声明[[noreturn]]但不是),或重新安排功能

int foo(int i) { 
    if (!(i>10)) 
     Exception::throwExcept(MyCustomException("Error: i not in the accepted range")); 

    return i*10; 
} 
1

它看起来对我来说,你的编译器无法看到里面Exception::throwExcept知道,它总是会抛出异常的。

帮助编译器使用原始C++异常throw作为函数的最后一行:throw std::exception("Just to help the compiler know to not warn here");这不会损害性能,因为代码并不会被执行。

+0

不幸的是,我仍然想使用我的'throwExcept'函数。长话短说,我使用嵌套的异常,但我的构建是跨平台的,并且MSVC版本不支持它们。因此,直到可以升级MSVC版本,我需要该函数在'std :: nested_exception'和这些的重新实现之间进行选择。 – JBL

+0

@JBL马克的意思是不要改变你的'throwExcept',而是要*添加一行''抛出'一些东西';'作为最后一行(永远不会到达)。 – Walter

+0

哦,好的。更有意义的是,我弄错了。 – JBL

2

抑制错误的一种快速和肮脏的方法是在return语句中使用逗号运算符。如果您使用

return Exception::throwExcept(MyCustomException("Error: i not in the accepted range")), 0; 

编译器会看到一个return语句,但它永远不会actualy执行作为

Exception::throwExcept(MyCustomException("Error: i not in the accepted range")) 

将引发它可以返回0

+4

这种攻击是不必要的,也很难阅读/理解。这是不好的做法。 – Walter

+1

诚然,它会比其他一些答案更不可读,更令人困惑。 :| – JBL

+1

@Walter我同意,但我会将它作为替代品。你的答案好多了(我喜欢围绕代码行简单的改变),并有我的投票。 – NathanOliver

7

阅卷Exception::throwExcept功能[[noreturn]]前应帮助编译器发现它实际上不会返回。

+0

在MSVC中,这将是'__declspec(noreturn)' –

+1

@CodyGray实际上,最新的MSVC版本接受'[[noreturn]]'(不知道哪个版本尽管...)。 – Holt

+0

那么,这可能是(我还没有证实对最近版本的支持),但提问者在另一个答案的评论中指出,他有一个包装函数抛出异常的全部原因是他使用了'std :: nested_exception',并且他的MSVC版本不支持,所以他需要根据工具链选择合适的实现。这表明他的MSVC版本将*不支持C++ 11属性。 –

相关问题