繁体   English   中英

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

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

这个问题不是如何删除警告

我正在写 shell。 我提到了这个来源 我在我的代码中使用了与他一样的标题(以相同的顺序)。

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

手册页建议使用#define _GNU_SOURCE ,并添加它从我的代码中删除了警告。

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


这是最少的代码(我复制了上面提到的所有标题)

// #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;
}

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

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

如果我留下第一行注释,这是我得到的错误。

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在拥有它的计算机上可用。

但是,您在编译代码时使用了编译器标志-std=c11 此标志的效果之一是 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当您尝试使用它时获得“隐式声明”诊断。

使用超-std=cXX模式几乎总是一个错误。 -std=cXX-std=gnuXX之间恰好有三个区别,在实践中它们都不是可取的:

  1. 如上所述,它指示标头不要声明任何不属于 ISO C 指定修订版的任何内容。 正如您亲眼所见,在编写一个重要的 C 程序时,这几乎不是您想要的。 它还具有破坏库头文件的令人讨厌的趋势——第三方头文件和 C 库自己的头文件——因为它们很少(如果有的话)在这种模式下进行测试。

  2. 它禁用污染用户命名空间的“ 系统特定的预定义宏”(例如linuxunixarm )。 这在抽象上是可取的,但与 #1 一样,有一种令人讨厌的倾向,即破坏在这种模式下很少(如果有的话)测试的库头。

  3. 启用trigraphs ,这是使 C 与缺少一些标点符号的 ASCII 的“国家变体”一起工作的一个组成部分。 这些很少使用并造成如此多的实际混乱,以至于它们实际上已从 C++ 2017(不是 C 2017)中删除。

要使用相当挑剔的一致性诊断级别编译您自己的代码,但又不冒破坏库头文件的风险,有更好的选项组合:

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

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

暂无
暂无

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

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