摆脱警告:flex 中函数“fileno”的隐式声明

Get rid of warning: implicit declaration of function ‘fileno’ in flex

我试图摆脱 gcc 在我尝试编译我的 bison 和 flex 文件时抛出的警告:

: In function ‘yy_init_buffer’:
:1675: warning: implicit declaration of function ‘fileno’

我想这样做的原因是因为我正在尝试向我正在参加的 class 提交作业,但我只能提交 "parser.y" 和 "scanner.l" 文件,它被远程编译。问题是:如果有警告(出于某种原因)它会被视为错误,并且因为我无法控制编译器标志,所以我无法让它消失。我在 Internet 上看到了一些关于相同问题的问题,但是 none 提到的解决方案对我有用。

编译器使用以下标志:

bison -d -o parser.c parser.y
flex -i -o scanner.c  scanner.l
gcc -std=c99 -pedantic -o test_parser *.c

我正在使用 Mac OSX 所以当我编译时它没有给我任何警告,所以我猜它是 linux 发行版的独特之处。这是我拥有的每个文件的 header 部分,以便您了解我已经尝试过的内容:

scanner.l

#define _POSIX_SOURCE 1
//#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
# include "parser.h"

parser.y

#include <stdio.h>
#include <stdlib.h>

int yylex (void);
void yyerror (char const *);

非常感谢您的帮助。

问题已通过添加到 flex 文件(暂时)解决:

int fileno(FILE *stream);

这是一种不好的做法,但这是我处理它的唯一方法。

我认为,传统答案是自我答案中列出的答案:手动声明 fileno

我通常的做法(也是我认为最常见的解决方案)是将 -D_XOPEN_SOURCE=700 添加到我的 gcc 标志中。 (700 比声明 fileno 所需的大,但有时我会使用其他 Posix 特性。)另一种方法是设置 _POSIX_C_SOURCE_POSIX_SOURCE 已弃用,但它仍然有效。

这些需要是编译器选项而不是 flex 输入文件中的 #defines,因为在生成的 flex 代码中,#include <stdio.h> 被插入到用户指定的序言之前,并且功能测试宏需要在第一次使用任何标准库头之前定义。 (有关详细信息,请参阅 man feature-test-macros and/or the Posix specification。)

由于这在您的编译环境中是不可能的,因此您需要使用变通方法。如前所述,一种是在序言中手动声明 fileno

另一种解决方法是通过指定 %option never-interactive 来避免调用 fileno,这会告诉 flex 生成一个扫描器,如果输入是终端,它不会尝试修改其行为。 %option always-interactive 也可以,但由于扫描仪不会在交互式环境中使用,因此这是不必要的开销。这些工作是因为 fileno 仅用于调用 isatty(这是 unistd.h 中的 Posix 函数)以决定是否激活交互式处理。如果您告诉 flex 输入始终或从不交互,则不需要此测试。 (如果您指定 read 选项以避免使用 stdio 进行输入,则还需要 fileno。但是您不需要也不应该。)

我有点惊讶您课程的编译环境在编译步骤中没有包含适当的功能测试宏定义。它应该这样做,您可以将我的建议传递给监督构建工具的任何人。