【问题标题】:How to enforce the usage of return values in C如何在 C 中强制使用返回值
【发布时间】:2021-10-14 14:12:06
【问题描述】:

我正在搜索 gcc 的编译器标志,如果可能的话,还有 clang 和 Microsoft 编译器,如果调用非 void 函数而不使用返回值,则会触发警告(-Werror 错误)这个:

int test() {
    return 4;
}

int main(void) {
    test(); //should trigger a warning
    int number = test(); //shouldn't trigger the warning
    return 0;
}

如果没有这样的编译器标志,也许有办法告诉clang静态分析器抱怨它。

编辑:为了澄清我最初的问题:我实际上是指使用返回值,而不仅仅是分配它。

【问题讨论】:

  • 注意 - 使用 int main (void) 而不是 void。 .
  • 这会导致很多不必要的警告。例如,每次调用printf() 都会产生投诉——他们返回打印的字符数,但没有人真正关心。
  • @Barmar,我可以看到这对于非库函数可能很方便。当我将返回值添加到以前的 void 函数时,我必须更改签名的其余部分,以寻找所有使用它的地方。
  • 或者您可以使用grep,或IDE 的内置搜索工具,例如“使用位置”。
  • 这里列出了所有 GCC 警告选项:gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

标签: c gcc


【解决方案1】:

我自己没用过(真的需要吗?),你可以试试

  • warn_unused_result属性定义函数
  • 使用gcc 启用-Wunused-result 标志。

这将告诉您函数返回中任何未使用的值。


如果有任何疑问,SEE IT LIVESEE IT LIVE AGAIN 感谢M.M评论中的链接

或者:

#include <stdio.h>

extern int func1(void) __attribute__((warn_unused_result));
extern int func2(void);

int main(void)
{
    func1();
    int rc1 = func1();
    int rc2 = func1();
    func2();
    printf("%d\n", rc1);
    return 0;
}

编译(Mac OS X 10.10.5 上的 GCC 5.1.0):

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c warn.c
warn.c: In function ‘main’:
warn.c:10:9: error: unused variable ‘rc2’ [-Werror=unused-variable]
     int rc2 = func1();
         ^
warn.c:8:5: error: ignoring return value of ‘func1’, declared with attribute warn_unused_result [-Werror=unused-result]
     func1();
     ^
cc1: all warnings being treated as errors
$

【讨论】:

  • @Andreas:是什么让你这么认为?
  • 如果他将结果分配给变量但不使用该变量,则会发出警告。当他没有将结果分配给变量时,他想要一个警告。
  • @Barmar:你确定吗?我认为“变量集但未使用”警告是分开的。
  • @JonathanLeffler 使用 OP 的代码,即使使用 -Wunused-result (gcc 4.8.4) 我也没有收到警告
  • @M.M 我也在做同样的事情。非常感谢,我也会在我的答案中添加您的链接。 :)
【解决方案2】:

splint 这样的一些静态代码分析器可以检查这些东西:

$ splint check.c
Splint 3.1.2 --- 03 May 2009

check.c: (in function main)
check.c:6:5: Return value (type int) ignored: test()
  Result returned by function call is not used. If this is intended, can cast
  result to (void) to eliminate message. (Use -retvalint to inhibit warning)

与@Sourav 的答案不同,这不需要在目标函数上使用特定的__attribute__ 注释,但另一方面可能会发出许多警告。通常可以通过使用注解(如/*@alt void@*/)来抑制特定函数或函数调用的警告。

【讨论】:

    猜你喜欢
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多