警告:忽略使用属性warn_unused_result声明的'scanf'的返回值

vip*_*pin 49 c

#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    printf("%d", t);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用ideone.com编译了上面的C代码,并弹出以下警告:

prog.c:在函数'main'中:
prog.c:5:警告:忽略'scanf'的返回值,使用属性warn_unused_result声明

有人能帮我理解这个警告吗?

Eva*_*ran 63

你的libc的作者已经决定scanf在大多数情况下不应该忽略返回值,所以他们给它一个属性告诉编译器给你一个警告.

如果真的不需要返回值,那么你没事.但是,通常最好检查它以确保您确实成功地阅读了您认为自己所做的事情.

在您的情况下,代码可以这样写,以避免警告(和一些输入错误):

#include <stdio.h>

int main() {
    int t;
    if (scanf("%d", &t) == 1) {
        printf("%d", t);
    } else {
        printf("Failed to read integer.\n");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 编译器仅对具有该特定属性的函数发出警告.如果`printf`失败,你可以做的不多.但是`scanf`很容易失败.我需要做的就是输入''A'而不是整数,你的程序就坏了. (8认同)
  • [这里是文档](http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bwarn_005funused_005fresult_007d-attribute-2552)关于GCC的`warn_unused_result`函数属性.如果你正在使用GCC(Ideone使用它)并查看你的`stdio.h`头文件,你会看到`scanf`及其亲属用`warn_unused_result`属性标记,但`printf`及其亲戚不是. (6认同)

Ale*_* C. 16

警告(正确)表示不检查返回值是一个坏主意scanf.如果您丢弃其返回值,scanf则已显式声明该函数(通过gcc函数属性)以触发此警告.

如果你真的想忘记这个返回值,同时保持编译器(和你的良心)满意,你可以将返回值转换为void:

(void)scanf("%d",&t);
Run Code Online (Sandbox Code Playgroud)

  • 即使您这样做,GCC仍会发出警告.有关详细信息,请参阅此讨论http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 (25认同)
  • @AffluentOwl"void"演员是标准惯例,说"这个结果是故意未使用"并得到普遍认可 - 除了gcc,因为有人(Stallmann?)在20年前决定不应该忽略`warn_unused_result`. (8认同)
  • 如果您分配给虚拟变量,那么您可能会收到另一个警告,关于已分配但从未使用过的变量. (4认同)
  • `(无效)!...` 至少可以用来避免 `gcc` 警告(@kraffenetti @AffluentOwl),参见 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34。 (4认同)
  • 警告:许多编译器将优化掉这个空转,因为它是不必要的,然后仍然会产生未使用的变量错误. (2认同)

Qui*_*igi 9

我用gcc(Ubuntu 4.4.3-4ubuntu5.1)4.4.3尝试了你的例子.当且仅当优化时,例如使用选项-O2或-O3发出警告.请求所有警告(-Wall)并不重要.铸造到虚空的经典习语没有效果,它不会抑制警告.

我可以通过写作来消除警告

if(scanf("%d",&t)){};
Run Code Online (Sandbox Code Playgroud)

这有效,但对我的口味来说有点模糊.Empty {}避免了另一个警告-Wempty-body

  • 这可能会导致编译器发出额外的空体警告 (2认同)
  • 如果我看到那种代码,在`if`的末尾加一个分号,我会认为它可能是一个错误.它至少需要一个解释性评论. (2认同)
  • 对于这样的ireesponsible,牛仔建议这么多赞成?不寒而栗 (2认同)

小智 5

做这个:

int main() {
    int t;
    int unused __attribute__((unused));
    unused = scanf("%d",&t);
    printf("%d",t);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 可悲的是,这看起来不太便携。 (2认同)