【问题标题】:Why can functions that return values be called without examining the returned value?为什么可以在不检查返回值的情况下调用返回值的函数?
【发布时间】:2019-03-07 17:27:56
【问题描述】:

我的意思是不将其值分配给变量并使用它。

例如:

int foo(void);
void main()
{
    foo();
}
int foo()
{
    return(5);
}

为什么我无法收到任何警告

【问题讨论】:

  • 我不知道你在这里问什么。
  • @RobertHarvey 他在问为什么当你调用非空函数而不使用值时编译器不打印警告。
  • 哦,你的意思是“你能把返回值扔掉吗?”当然。
  • @EugeneSh。当然,但编译器经常警告看起来可疑的“完全有效”代码。它们已经发展到包含许多以前在 lint 中的功能。
  • 要考虑的一点:printf返回一个值。

标签: c function


【解决方案1】:

许多函数返回一个值并执行副作用,但它们通常仅用于副作用。

例如,printf() 打印输出并返回打印的字符数。但是大多数时候返回值并不有趣,所以我们不会在任何地方分配它。 fclose() 返回一个成功指示符,但如果程序失败通常无能为力,因此它们不会费心检查结果。

写这样的东西会很乏味:

(void)printf(...);
(void)fclose(f);

始终如此,因此编译器通常不会在不使用结果的情况下调用非 void 函数发出警告。

在某些情况下,这可能是个问题。有些函数确实应该使用返回值,但不使用它是一个常见的错误。例如,realloc() 返回新指针,但许多初学者只是假设它总是会调整旧指针指向的分配大小。

出于这个原因,某些 IDE 可能具有应发出警告的函数列表。但是编译器通常没有那么精确。

【讨论】:

  • @chux 好点,虽然另一个问题是你应该将它分配给一个临时变量,检查是否成功,然后才重新分配原始指针。 p = realloc(p, new_size); 将通过“is value used”测试,但仍不是防御性编程。
【解决方案2】:

如果您不想,您没有义务存储或检查函数返回的值。

例如,printf 返回一个int 表示成功写入的字符数,但大多数时候您只需调用printf 即可在屏幕上产生输出;你不关心返回值。例如:

printf("Hello World!\n");

比以下更常见:

if(printf("Hello World!\n") != 13)
    // printf failed

也就是说,有很多静态分析工具可以强制调用某些函数的代码必须检查它们的返回值。我最熟悉的SAL 允许您使用_Check_return__Must_inspect_result_ 来注释函数,如果您随后调用这样注释的函数而不检查其返回值,分析将报告警告。

例子:

_Must_inspect_result_
int foo()
{
    return 5;
}

int main(void)
{
    foo();
    return 0;
}

对此代码运行 SAL 分析会产生警告消息:

C6031 忽略返回值:'foo'。

【讨论】:

    猜你喜欢
    • 2015-10-04
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 2012-02-24
    • 1970-01-01
    • 2017-11-25
    • 2017-05-21
    相关资源
    最近更新 更多