隐式声明"getline"函数的警告在一个代码中引发,但在另一代码中则没有 [英] implicit declaration of function ‘getline’ warning thrown in one code, but not in another

查看:97
本文介绍了隐式声明"getline"函数的警告在一个代码中引发,但在另一代码中则没有的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题不是要删除的警告

我正在写一个shell.我引用了此来源.我在代码中使用了与他相同的标题(顺序相同).

I am writing a shell. I referred this source. I used the same headers (in the same order), as he did, in my code.

在编译他的代码时,对于 getline 隐式声明,我没有收到任何警告.但是当我编译我的时,它确实会被抛出.

When compiling his code, I do not get any warnings for implicit declaration of getline. But when I compile mine, it does get thrown.

该手册页建议使用 #define _GNU_SOURCE ,并添加该内容以删除我的代码中的警告.

The man page suggests to use #define _GNU_SOURCE, and adding that removed the warning from my code.

那他为什么不对博客中的代码发出警告,因为他没有使用 #define _GNU_SOURCE ?

So why was no warning thrown for the code in the blog, as he did not use #define _GNU_SOURCE?

这是最少的代码(如上所述,我复制了所有标头)

Here is the minimal code (I copied all the headers as I mentioned above)

// #define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
  ssize_t bytes_read;
  size_t input_buffer_size = 1024;
  char *user_input = (char *)malloc(input_buffer_size * sizeof(char));

  while (1)
  {
    printf("> ");
    bytes_read = getline(&user_input, &input_buffer_size, stdin);

    printf("%s\n", user_input);
  }

  return 0;
}

这是我使用的编译过程...

And here is the compilation process I used...

gcc -std=c11 -o bin/shell src/shell.c

这是如果我保留第一行的注释,则会出现错误.

Here is the error that I get if I leave the first line commented.

src/shell.c: In function ‘main’:
src/shell.c:18:18: warning: implicit declaration of function ‘getline’ [-Wimplicit-function-declaration]
   18 |     bytes_read = getline(&user_input, &input_buffer_size, stdin);
      |                  ^~~~~~~

推荐答案

看来您编写的教程的编写人员在测试代码时未提供任何特殊的编译选项.我在该页面上的任何地方都只看到一个编译命令,它是 gcc -o main main.c .因此,他们获得了GCC的默认设置,通常使 getline 在拥有它的计算机上可用.

It appears that the person who wrote the tutorial you're referring to, did not supply any special compilation options when they were testing their code. I see only one compilation command anywhere on that page, and it is gcc -o main main.c. Thus, they got GCC's defaults, which, typically, make getline available on computers that have it.

但是,您在编译代码时使用了编译器标志 -std = c11 .该标志的作用之一是,GCC指示C库的标头仅声明 ISO C2011指定的函数,常量,变量等.(根据您使用的是哪个C库,此指令可能会或可能不会有任何效果-但Ubuntu使用GNU C库,它会彻底实现它.) getline 不是ISO C2011的一部分,因此它不会被声明,并且您会收到隐式声明"尝试使用时进行诊断.

You, however, used the compiler flag -std=c11 when you compiled your code. One of the effects of this flag is that GCC directs the C library's headers to declare only the functions, constants, variables, etc. that are specified by ISO C2011. (Depending on which C library you're using, this directive may or may not have any effect — but Ubuntu uses the GNU C library, which implements it thoroughly.) getline is not part of ISO C2011, so it is not declared and you get an "implicit declaration" diagnostic when you try to use it.

使用超一致性 -std = cXX 模式几乎总是一个错误. -std = cXX -std = gnuXX ,在实践中都不希望使用它们:

Use of the hyperconformant -std=cXX modes is almost always a mistake. There are exactly three differences between -std=cXX and -std=gnuXX and none of them is desirable in practice:

  1. 如上所述,它指示标头不要声明不属于ISO C指定版本的任何内容.正如您自己所看到的那样,编写非平凡的C程序几乎从来都不希望这样做.它还有破坏库标头(第三方标头和C库自己的标头)的讨厌趋势,因为很少(如果有的话)在这种模式下对其进行测试.

  1. As discussed above, it directs the headers not to declare anything that's not part of the specified revision of ISO C. As you saw for yourself, this is almost never what you want when writing a nontrivial C program. It also has a nasty tendency to break library headers — both third-party headers and the C library's own headers — because they are rarely, if ever, tested in this mode.

它会禁用" 系统特定的预定义宏"污染用户名称空间(例如 linux unix arm ).从抽象上讲,这是理想的选择,但与#1一样,它有一种令人讨厌的趋势,即破坏库标头,而这种标头很少(如果有的话)在这种模式下进行过测试.

It disables "system-specific predefined macros" that pollute the user namespace (e.g. linux, unix, arm). This is abstractly desirable but, like #1, has a nasty tendency to break library headers that are rarely, if ever, tested in this mode.

启用 三部曲,它们是努力使C与国家变体"一起使用缺少一些标点符号的ASCII码.这些很少使用,并且造成了太多实际混乱,以至于实际上它们被从C ++ 2017中剥离出来了(尽管不是C 2017).

It enables trigraphs, which are a kludge to make C work with "national variants" of ASCII that are missing some punctuation. These are so rarely used and cause so much practical confusion that they were actually stripped out of C++ 2017 (not C 2017, though).

要编译具有合理挑剔级别的一致性诊断程序的自己的代码,但又不冒破坏库标头的风险,可以使用以下选项的更好组合:

To compile your own code with a reasonably picky level of conformance diagnostics, but not risk breaking library headers, there is a better combination of options:

cc -std=gnuXX -g -Og -Wall -Wextra -Wpedantic -Wold-style-definition -Wwrite-strings

(选择一个合适的XX;如果您没有理由选择其他任何东西,我会选择11.)您可能会或可能不想为其中一个添加 -D 开关. _xxx_SOURCE 功能选择宏;解释这些工作原理以及如何选择它们本身就是一个完整的问题.

(Pick a suitable XX; if you have no reason to choose anything else, I'd go with 11.) You may or may not want to add a -D switch for one of the _xxx_SOURCE feature selection macros; explaining how those work and how to choose one is a whole question in itself.

这篇关于隐式声明"getline"函数的警告在一个代码中引发,但在另一代码中则没有的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆