簡體   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