【问题标题】:How to use asprintf in a flex rule, when _GNU_SOURCE not set?当 _GNU_SOURCE 未设置时,如何在 flex 规则中使用 asprintf?
【发布时间】:2016-01-04 17:19:58
【问题描述】:

为了保证asprintf函数在头文件<stdio.h>中可见,我按照手册页的建议放了:

#define _GNU_SOURCE
#include <stdio.h>
// ... uses of asprintf();

这适用于普通的 C 程序,尽管可能只适用于 GNU/Linux 而不是 BSD。

我希望能够在弹性词法分析器中使用相同的技巧,例如:

%{
#define _GNU_SOURCE
#include <stdio.h>
%}

%%

\"[^\"].+\" {
  asprintf(&(yylval.string), "%s", yytext);
  return STRING;
}

%%

// ...

但我收到asprintf 的编译警告 (implicit-function-declaration)。

进一步调查,这是因为在 flex 生成的 C 文件中,在我的序言代码之前包含 &lt;stdio.h&gt;,而没有先定义 _GNU_SOURCE。

我怎样才能写出使用这个函数的代码

  • 在 flex 规则中正确编译,并且
  • 可选)也适用于非 GNU 环境?

【问题讨论】:

  • 另一种方法是调整您的构建系统以通过-D_GNU_SOURCE
  • 但是,如果 flex 使用该标头而没有该声明,则有可能会改变其行为。但这也会奏效,是的。
  • 这真的很奇怪。

标签: c flex-lexer


【解决方案1】:

重新检查了the book,这让我养成了使用asprintf的习惯,我发现它确实是一个GNU扩展。

它位于名为 libiberty 的 GCC 库中,您可以使用它来代替 _GNU_SOURCE 宏。

我能够在 Ubuntu 15.10 和 Debian 8.2 上使用:

sudo apt-get install libiberty-dev

然后我修改了序言以包括:

%{
#include <libiberty/libiberty.h>
%}

一切正常,没有任何警告。

假设一个 libiberty 包可用于非 Linux 发行版(并且鉴于它是 GCC 的一部分,我会假设是这种情况)这个解决方案应该可以跨平台工作(在 POSIX-ish 操作系统上)。

【讨论】:

  • 你可能想看看stackoverflow.com/a/30687023/1566221。如果您将对 asprintf 的调用抽象到一个支持库,您只需要包含该库的标头,您还可以隐藏基础结构来决定使用哪个版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-24
相关资源
最近更新 更多