【问题标题】:Return value ignored [scanf]返回值被忽略 [scanf]
【发布时间】:2021-10-03 09:51:39
【问题描述】:

我正在使用 C 语言。 我知道每个函数都有返回值(void 函数除外)。 但 C6031 警告信息仅出现在 scanf 函数中。 它不会出现在 printf 或 hello 等其他函数中(如下所示)。 为什么会出现这种现象?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int hello(void) {
    printf("Hello World!");
    return 10;
}

int main(void) {
    int i;
    scanf("%d", &i);

    hello();
    return 0;
}

【问题讨论】:

  • 因为重要的是不要忽略scanf()的返回值来检查它是否成功读取了一些数据并且不要使用未初始化的值导致意外行为。
  • 检查printf 返回的值也相当重要,但大多数程序依赖于伴随SIGPIPE 的printf 失败。大多数程序员要么对 SIGPIPE 的终止感到满意,要么不知道,要么不在乎。当他们在某个 SIGPIPE 被意外忽略的环境(例如 python 子进程)中运行他们的代码时,它突然变成了一个问题。
  • 如果printf 失败,您可能几乎无法采取补救措施,但如果scanf 失败,很可能是用户输入错误,程序几乎总是需要一些补救措施(比如重新提示)。这使得检查scanf 成为正常功能的重要组成部分。
  • 关于它是如何工作的问题:很可能在某个地方,可能在像&lt;stdio.h&gt; 这样的头文件中,您的环境正在使用一些非标准机制来指示哪些功能(如printf)可以安全地忽略它们的返回值,而不是应该警告哪些函数(如scanf)。
  • 我重新打开了这个问题,因为副本回答了“为什么忽略 scanf 的返回值很危险”的问题,但这里的实际问题是“为什么这个警告会出现在某些函数中而不是为他人。”那可能也是重复的,但我找不到。

标签: c


【解决方案1】:

正如@SteveSummit 在评论中指出的那样,大多数 C 实现都有一种机制来识别不应忽略其返回值的函数。

C 本身(由 C 标准定义)总是允许调用者忽略函数的返回值。它甚至允许声明为返回值类型的函数不返回任何值,只要所有调用者都忽略返回值。

但是,这种宽容通常不会带来良好的编程习惯。在某些情况下,忽略函数的返回值很可能会导致错误。 scanf 被认为是这样一个函数,因此标准库的作者倾向于将scanf 标记为要求使用返回值。

没有标准方法可以将函数标记为需要使用其返回值。在 GCC 和 Clang 中,这是使用属性 warn_unused_result 完成的:

int fn (int a) __attribute__ ((warn_unused_result));

(请参阅the warn_unused_result function attribute 的 GCC 文档以及如何关闭警告(不推荐):the `-Wno-unused-result。)

在 MSVC 中,它是通过 _Check_return_ 宏完成的,位于 sal.h

#include <sal.h>
_Check_return_ int fn (int a);

(参见the Visual Studio docs for error C6031this documenation on the Source Annotation Library (sal)。)

有充分的理由不忽略任何使用返回值指示失败的库函数的返回值,包括许多执行输入或输出的标准库函数。忽略输入或输出失败可能会导致问题,但忽略输入失败时问题会更加明显,因为这可能导致使用未初始化的值,进而导致未定义的行为。 scanf 肯定是这种情况:忽略它的返回值意味着您的程序将无法正确响应格式错误的输入,这几乎可以肯定是一个错误。

忽略输出函数的失败有时意味着用户不会收到有关无法保存持久数据的警告。这可能很严重,很可能需要采取一些措施来保存这些数据。但在其他情况下,错误只是意味着用户没有看到一些日志消息,并且很可能也不会看到未来的日志消息。这可能并不重要。

【讨论】:

    猜你喜欢
    • 2021-01-31
    • 2018-04-02
    • 2015-04-06
    • 1970-01-01
    • 2021-01-13
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多