首先在 lex 中添加要编译的代码

Adding a code to be compiled in lex first

我正在寻找一种方法来将 #undef 插入到 lex 生成的源代码中,该源代码将出现在 lex 生成的内置行之前。

当用 lex 编译 file.l 时,我生成了一个 lex.yy.c 文件。在我的 file.l 中,我写了:

#include "y.tab.h"
#undef __STRICT_ANSI__
#include <string.h>

#undef 帮助我编译标记 -std=c99 下的代码,因此需要在包含 string.h 之前完成。但是生成的文件在复制我的 undef.

之前包含 string.h

如果没有 #undef,由于使用 strdup,我会收到很多警告。我已经看到使用标志的正常修复,但就像我说的那样我无法访问 makefile。

添加'manually'行

#undef __STRICT_ANSI__

到 lex.yy.c 之前修复所有问题。但我不想接触任何生成的代码,而是让 lex 完成它。

我读过这个, strdup(): Confused about warnings ('implicit declaration', 'makes pointer...without a cast', memory leak) 就像我说的那样,它确实解决了它。 但前提是我能以某种方式强制生成的文件先 运行 undef。

首先,#undef __STRICT_ASCII__ 不是 启用 Posix 函数声明的正确方法,例如 strdup.

Posix 在标准 C 库头文件中声明的扩展以 "feature test macros" 为条件。您可以在 man feature_test_macros but in any case, the documentation for any function which requires a feature test macro includes a description of which macros are required. In the case of strdup, we can read in man strdup:

中阅读摘要

glibc 的功能测试宏要求(参见 feature_test_macros(7)):

   strdup():
       _XOPEN_SOURCE >= 500

(后面还有更多的可能性。)

就个人而言,我总是使用

#define _XOPEN_SOURCE 700

要求声明最新版本 Posix 中的所有函数。

在标准库函数的任何包含之前插入功能测试宏的一种方法是在编译命令行上这样做:

-D_XOPEN_SOURCE=700

我喜欢这样做,因为我可以将它添加到我的 Makefile 中,然后它适用于每个编译(这基本上是我想要的)。通常,makefile 包含一项功能,允许您在不修改文件的情况下将此选项添加到编译器标志。例如,以下内容通常有效:

make file CPPFLAGS="-D_XOPEN_SOURCE=700"

CPPFLAGS 是一个常用的 makefile 变量,用于设置预处理器标志。)

但是如果你想把它放到你的 flex 文件中,你可以使用一个 %top 块:

%top {
#define _XOPEN_SOURCE 700
}

%top 类似于 %{,但它将插入的代码放在生成代码的开头。


如果其他方法都不起作用,您可以随时将 strdup 的声明(也取自 man strdup)插入到您的 flex 序言中。

%{
  char *strdup(const char *s);
  #include "y.tab.h"
%}

C 标准和 Posix 标准都允许显式声明库函数(但不是宏)作为包含相关头文件的替代方法。