【问题标题】:How do I remove the following 'implicit declaration of function' warnings?如何删除以下“函数的隐式声明”警告?
【发布时间】:2012-02-24 07:45:05
【问题描述】:

如何使用 gcc 编译 lex 文件而不收到以下警告?

lex.yy.c: In function `yy_init_buffer':
lex.yy.c:1688: warning: implicit declaration of function `fileno'
lex.l: In function `storeLexeme':
lex.l:134: warning: implicit declaration of function `strdup'

这些是我包含的库。

%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
%}

函数 yy_init_buffer 不在文件中。下面是函数storeLexeme。

 int storeLexeme() {
for (int i = 0; i < count; i++) {
    char *curr = *(symbolTable + i); 
    if (strcmp(curr, yytext) == 0) {
        return i;
    }
}
char *lexeme = (char *)malloc(sizeof(char *));
lexeme = (char *)strdup(yytext);
symbolTable[count] = lexeme;
count++;
return (count - 1);
 }

如何删除警告?

【问题讨论】:

  • 我更改了 flex 标签,因为它是关于 Adob​​e flex 而不是 GNU lex 克隆。
  • 什么平台,UNIX 还是 Windows?
  • 那些不是“库”;它们是“标题”。链接行中使用了库;源代码引用标题。

标签: c lex


【解决方案1】:

strdupfileno 都不是 ISO C 函数,它们是 POSIX 的一部分。

现在它们是否在您的平台上可用取决于您的平台。


如果您使用的是 Microsoft 工具,您可能需要查看 _fileno 的后者(VC2005 中的 fileno was deprecated)。 strdup 的一个相当优秀的版本可以在 here 找到。

尽管我已经用那个代码吹响了我自己的号角,但您也可以使用_strdup,因为它取代了also-deprecated strdup :-)

这些应该可以正常工作,因为它们位于 stdio.hstring.h,这是您已经在使用的两个包含文件。


如果您使用的是 UNIX 衍生产品,这些功能应该在 stdio.hfileno)和string.hstrdup)中可用。鉴于您似乎已经包含了这些文件,问题可能出在其他地方。

一种可能性是,如果您在其中一种严格模式(如 gcc 中的 __STRICT_ANSI__)下进行编译,则两者都不会被定义。

您应该查看生成的 lex.yy.clex.l 文件的顶部,以确认包含头文件,并检查您传递给的命令行参数编译器。

【讨论】:

  • _fileno,如果使用MS工具,也有_strdup
  • 想在这里补充一下,我正在使用 Linux (debian/ubuntu) 并且必须使用 -D _GNU_SOURCE 进行编译才能让编译器从 wchar.h 中识别这个函数
【解决方案2】:

我建议这个选项(告诉编译器你正在使用 POSIX):

#define _POSIX_C_SOURCE 1

近年来人们似乎收紧了功能控制,希望当一致性良好且广泛使用时,我们可以扔掉 automake 垃圾。

【讨论】:

  • 你可以考虑在Makefile(或Makefile.am)中添加一次-D_POSIX_C_SOURCE=1
【解决方案3】:

我在使用 flex 时也遇到了这个问题。

我使用-std=gnu99而不是-std=c99 解决了这个问题。

flex lang.l && gcc -o lexer -std=gnu99 lex.yy.c -lfl                         

【讨论】:

    【解决方案4】:

    考虑添加以下行:

    extern char *strdup(const char *s);
    

    我在使用-std=c99 -pedantic -pedantic-errors 编译时遇到了这个问题。添加上面的行解决了我的问题。

    【讨论】:

    • extern 在这里是多余的。无论如何,它是一个函数声明,并且没有 static 关键字,它的链接是外部的。
    • 对,就这么简单
    【解决方案5】:

    在使用之前声明函数:

    //declare the function
    int storeLexeme();
    
    //use the function here
    

    或包含声明函数的标头。

    C 隐含地假定未声明的函数具有返回类型int,并根据您调用函数的方式推断出参数。这在 C++ 中已弃用。

    【讨论】:

    • 我确实在#included 库之后使用它之前声明了该函数,但我仍然收到警告。
    • 它抱怨的不是 storeLexeme 函数,而是 strdup 从那里调用
    • 您是否还声明了strdupfileno 或包含标题?
    • @paxdiablo 是的,我现在看到了,但原理还是一样的。
    【解决方案6】:

    只要把你的函数放在库调用下面就可以了;

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多