如果返回值被忽略,如何提出警告?

我想看看我的代码中的所有地方(C ++)忽略函数的返回值。 我该怎么做 – 用gcc或静态代码分析工具?

错误代码示例:

int f(int z) { return z + (z*2) + z/3 + z*z + 23; } int main() { int i = 7; f(i); ///// <<----- here I disregard the return value return 1; } 

请注意:

  • 即使该function及其用途在不同的文件中也应该起作用
  • 免费的静态检查工具

你想要GCC的warn_unused_result属性:

 #define WARN_UNUSED __attribute__((warn_unused_result)) int WARN_UNUSED f(int z) { return z + (z*2) + z/3 + z*z + 23; } int main() { int i = 7; f(i); ///// <<----- here i disregard the return value return 1; } 

试图编译这个代码产生:

 $ gcc test.c test.c: In function `main': test.c:16: warning: ignoring return value of `f', declared with attribute warn_unused_result 

你可以看到这个在Linux内核中使用; 他们有一个__must_checkmacros来做同样的事情; 看起来像你需要GCC 3.4或更高的工作。 然后你会发现在内核头文件中使用的macros:

 unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n); 

据我所知,没有GCC选项给这个警告。 但是,如果您对特定function感兴趣,则可以使用以下属性对它们进行标记:

 int fn() __attribute__((warn_unused_result)); 

如果没有使用fn()的返回值,会发出警告。 警告:我从来没有使用过这个function。

你可以使用这个方便的模板在运行时做到这一点。

您将返回一个return_code <HRESULT>,而不是返回错误代码(例如HRESULT),如果该值超出范围,则不会读取值。 这不是一个静态分析工具,但它是有用的。

 class return_value { public: explicit return_value(T value) :value(value), checked(false) { } return_value(const return_value& other) :value(other.value), checked(other.checked) { other.checked = true; } return_value& operator=(const return_value& other) { if( this != &other ) { assert(checked); value = other.value; checked = other.checked; other.checked = true; } } ~return_value(const return_value& other) { assert(checked); } T get_value()const { checked = true; return value; } private: mutable bool checked; T value; }; 

任何静态分析代码(如PC-Lint )都应该能够告诉你。 对于PC-Lint,我知道这是事实。

一个静态分析器会为你做这个工作,但是如果你的代码基础更为微不足道的准备被压倒;-)

静态分析仪将是你最好的select。 我们在这里使用Coverity,但也有可用的免费工具 。

如果你需要一个快速而又脏的解决scheme,并且你有一个Linux风格的shell,你可以尝试如下的东西:

 grep -rn "function_name" * | grep -v "=" 

这将find每一行引用指定的function,但不包含“=”。 你可以得到很多误报(可能会有一些误报),但是如果你没有静态分析器,那么这是一个不错的开始。

经典的“lint”程序过去常常会返回一个被忽略的值。 麻烦的是,许多这些警告是不必要的 – 导致皮棉输出过度的噪音(它正在捡起一些你想忽略的绒毛)。 这可能是为什么海湾合作委员会没有一个标准的警告。

另一个问题 – 另一方面 – 是“当你知道自己忽略了结果但是真的不在乎时,你怎么压制这个警告”。 经典的情况是:

 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, sighandler); 

你关心signal()的第一个结果。 你知道第二个将是SIG_IGN(因为你只是把它设置为)。 为了摆脱这些警告,我有时使用一些变体:

 if ((old = signal(SIGHUP, SIG_IGN)) != SIG_IGN) old = signal(SIGHUP, sighandler); 

这分配到old时代。 你可以通过'assert(old == SIG_IGN)'来实现。