忽略C中的返回值

std*_*all 41 c coding-style lint return-value

最近,我开始使用lint进行静态代码分析.我有时得到的一个警告就是这个问题.比方说,我有以下功能:

uint32_t foo( void );
Run Code Online (Sandbox Code Playgroud)

让我们说我故意忽略函数的返回值.为了使警告消失,人们可以写

(void) foo();
Run Code Online (Sandbox Code Playgroud)

我的问题是,编写这样的代码的"正确"方法是什么,我应该像往常一样继续,因为编译器不会抱怨它,或者我应该使用void来清楚,所以其他代码维护者会知道我刻意忽略了返回值.

当我看到这样的代码(带有空白)时,我觉得很奇怪......

mou*_*iel 56

常见的方法是在foo();不投入的情况下打电话(void).

从来没有忽视过printf()回报价值的人,铸就了第一块石头.

  • 我认为我个人在实际实现printf返回值xD之前的时间最长. (7认同)
  • +1是唯一能理解问题的4个答案.不知道为什么其他人都错过了这一点. (6认同)
  • 这样做不起作用.看看@dfsmith的答案 (3认同)

小智 30

我个人比较喜欢的"未使用"的警告,但有时也有,我都不理他们(实例例如,write()用户,或fscanf(...,"%*s\n")strtol()在返回值是不重要的,我只是想的副作用[也许]移动文件指针.)

使用gcc 4.6,它变得非常棘手.

  • 铸造(void)不再有效.
  • 重写函数(尤其是可变参数)是繁琐且笨拙的.
  • {ssize_t ignore; ignore=write(...);} 抛出另一个警告(已分配 - 未使用).
  • write(...)+1 抛出另一个警告(计算值 - 未使用).

抑制这些的唯一好处(如果丑陋)是将返回值转换为编译器同意您可以忽略的内容.

例如,(void)(write(...)+1).

这显然是进步.(并且+0不起作用,BTW.)

  • `if(write(...));`也应该工作.不要忘记拖尾分号`;`. (3认同)
  • `(void)!foo(); /*与 gcc4.6+ 一起使用 */` 最好放在宏或内联函数中。最好使用支持**不能忽略**的工具。有些回报是提供信息的,有些则至关重要。 (2认同)

Ale*_*lds 17

使用Clang和GCC编译器执行此操作的一种方法是pragma:

    /* ... */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result" 

    foo(); /* this specific unused-result warning gets ignored during compilation */

#pragma GCC diagnostic pop 

    /* ... */
Run Code Online (Sandbox Code Playgroud)

push- pop组合包装的ignored指令,这样的警告可以在其他地方在你的代码被触发.对于那些阅读源代码的人来说,看看这个代码块的功能应该会更容易.


jde*_*aan 9

要使静态代码检查器有用,它还应报告忽略的返回值,这可能导致很难跟踪错误 - 或者错过错误处理.

所以你应该保持(void)或停用支票printf.现在,您可以通过多种方式以可读的方式执行此操作.我用来将函数包装在一个新函数中,例如

void printf_unchecked(const char* format, ...)
Run Code Online (Sandbox Code Playgroud)

不太好的演员阵容发生的地方.也许在这种情况下使用预处理器宏来实现它更实际,因为varargs ...

  • +1,即使我个人更喜欢简单的`(void)`cast.感谢您理解问题并提供不同的方法 (2认同)
  • 我喜欢使用预处理器宏的想法.也许类似于:#define UNCHECKED_RV(function_call)(void)function_call这个解决方案或function_unchecked()包装器的好处是它非常清楚你是故意忽略返回值.铸造到虚空并不是那么清楚. (2认同)

mic*_*c_e 9

指示未使用结果的一种稍微"漂亮"的方式是:

/**
 * Wrapping your function call with ignore_result makes it more clear to
 * readers, compilers and linters that you are, in fact, ignoring the
 * function's return value on purpose.
 */
static inline void ignore_result(long long int unused_result) {
    (void) unused_result;
}

...

ignore_result(foo());
Run Code Online (Sandbox Code Playgroud)

有了C++,这可以扩展到:

template<typename T>
inline void ignore_result(T /* unused result */) {}
Run Code Online (Sandbox Code Playgroud)

  • 这是我的首选解决方案。但是,我必须说,可以正常工作的C示例将是:`static inline void ignore_result(ssize_t used){(void)unused; }`,因为您无法像在C ++中那样在C中省略参数标识符。同样,对于gcc,如果您不添加`static`,则在禁用优化后会生成链接器错误。 (3认同)
  • 感谢您的注意; 我已经相应地修正了我的答案. (2认同)

Dr *_*eco 6

我喜欢用标志来编译代码:

$gcc prog1.c -o prog1.x -Wall -Wextra -ansi -pedantic-errors -g -O0 -DDEBUG=1
Run Code Online (Sandbox Code Playgroud)

为了避免这种情况,-Wunused-result我不喜欢添加另一个标志的想法:(-Wno-unused-result如果这样做,那就是一个解决方案)。

我曾经强制转换(void)为某些函数(不printf编译或不使用其他著名函数,因为编译器不会警告它们,只是奇怪的函数)。现在强制转换为(void)不再起作用(GCC 4.7.2)

有趣的夹板建议:

Result returned by function call is not used. If this is intended,
can cast result to (void) to eliminate message. (Use -retvalother to
inhibit warning)
Run Code Online (Sandbox Code Playgroud)

但这不再是解决方案。夹板需要有关此问题的更新。

因此,以一种非常兼容的方式摆脱警告,这是一个好习惯MACRO

/** Turn off -Wunused-result for a specific function call */
#define igr(M) if(1==((int)M)){;}
Run Code Online (Sandbox Code Playgroud)

并这样称呼它:

igr(PL_get_chars(t, &s, CVT_VARIABLE));
Run Code Online (Sandbox Code Playgroud)

它的外观整洁,任何编译器都将省去代码。下面是我最喜欢的编辑的照片vi:左窗,否igr();中间窗口,使用igr(); 右窗口,来源。

在此处输入图片说明

您可以看到,完全相同的完全无害的代码让C做gcc不会做的事情:忽略返回代码。

1==...仅为了避免夹板警告此条件为否,才需要进行比较BOOL。海湾合作委员会一点也不在乎。根据功能,您可能会收到cast警告。我进行了一个测试,忽略了double这个MACRO,这很好,但是我不完全相信。特别是如果函数返回指针或更复杂的东西。

在这种情况下,您还需要:

#define pigr(M) if(NULL==((void *)M)){;}
Run Code Online (Sandbox Code Playgroud)

最后一件事:{;}由于出现-Wempty-body警告,所以这是必需的(在“ if”语句中,建议将大括号括在空主体周围)。

并且(现在是最后一件事);函数调用之后(严格地)不是必需的,而是良好的实践。使您的代码行更加同质,所有代码行均以结尾;。(它被翻译为NOP助记符,经过优化后消失了)。


运行编译器不会发出警告或错误。运行splint给出:

$ splint ./teste.c -I/usr/lib/swi-prolog/include/ -strict-lib
Splint 3.1.2 --- 20 Feb 2009

Finished checking --- no warnings
Run Code Online (Sandbox Code Playgroud)

另请参阅此答案