简体   繁体   English

function 'getline' 警告的隐式声明在一个代码中引发,但在另一个代码中没有

[英]implicit declaration of function ‘getline’ warning thrown in one code, but not in another

THIS QUESTION IS NOT HOW TO REMOVE THE WARNING这个问题不是如何删除警告

I am writing a shell.我正在写 shell。 I referred this source .我提到了这个来源 I used the same headers (in the same order), as he did, in my code.我在我的代码中使用了与他一样的标题(以相同的顺序)。

When compiling his code, I do not get any warnings for implicit declaration of getline .在编译他的代码时,我没有收到任何关于getline隐式声明的警告。 But when I compile mine, it does get thrown.但是当我编译我的时,它确实被抛出了。

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 ?那么为什么没有对博客中的代码发出警告,因为他没有使用#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);
      |                  ^~~~~~~

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 .我在该页面的任何地方只看到一个编译命令,它是gcc -o main main.c Thus, they got GCC's defaults, which, typically, make getline available on computers that have it.因此,他们得到了 GCC 的默认值,通常情况下,它使getline在拥有它的计算机上可用。

You, however, used the compiler flag -std=c11 when you compiled your code.但是,您在编译代码时使用了编译器标志-std=c11 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.此标志的效果之一是 GCC 指示 C 库的头文件声明 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. (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当您尝试使用它时获得“隐式声明”诊断。

Use of the hyperconformant -std=cXX modes is almost always a mistake.使用超-std=cXX模式几乎总是一个错误。 There are exactly three differences between -std=cXX and -std=gnuXX and none of them is desirable in practice: -std=cXX-std=gnuXX之间恰好有三个区别,在实践中它们都不是可取的:

  1. As discussed above, it directs the headers not to declare anything that's not part of the specified revision of ISO C.如上所述,它指示标头不要声明任何不属于 ISO C 指定修订版的任何内容。 As you saw for yourself, this is almost never what you want when writing a nontrivial C program.正如您亲眼所见,在编写一个重要的 C 程序时,这几乎不是您想要的。 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.它还具有破坏库头文件的令人讨厌的趋势——第三方头文件和 C 库自己的头文件——因为它们很少(如果有的话)在这种模式下进行测试。

  2. It disables " system-specific predefined macros " that pollute the user namespace (eg linux , unix , arm ).它禁用污染用户命名空间的“ 系统特定的预定义宏”(例如linuxunixarm )。 This is abstractly desirable but, like #1, has a nasty tendency to break library headers that are rarely, if ever, tested in this mode.这在抽象上是可取的,但与 #1 一样,有一种令人讨厌的倾向,即破坏在这种模式下很少(如果有的话)测试的库头。

  3. It enables trigraphs , which are a kludge to make C work with "national variants" of ASCII that are missing some punctuation.启用trigraphs ,这是使 C 与缺少一些标点符号的 ASCII 的“国家变体”一起工作的一个组成部分。 These are so rarely used and cause so much practical confusion that they were actually stripped out of C++ 2017 (not C 2017, though).这些很少使用并造成如此多的实际混乱,以至于它们实际上已从 C++ 2017(不是 C 2017)中删除。

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

(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 ; (选择一个合适的 XX;如果您没有理由选择其他任何东西,我会选择 go 和 11。)您可能想要也可能不想为_xxx_SOURCE 功能选择宏之一添加-D开关; explaining how those work and how to choose one is a whole question in itself.解释这些是如何工作的以及如何选择一个本身就是一个完整的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM