【问题标题】:Partially preprocess a C or C++ source file?部分预处理 C 或 C++ 源文件?
【发布时间】:2011-09-22 20:44:05
【问题描述】:

有没有办法对 C 或 C++ 源文件进行部分预处理? “部分预处理”是指扩展一些但不是全部的#include 指令。例如,我想扩展#includes 指向我的项目头文件,而不是#includes 指向其他库的头文件。

我尝试通过运行 gcc -E 来做到这一点,只为我的项目标头使用 -I 标志,而不是为库使用 -I 标志,但这不起作用,因为 gcc 在遇到#include 不能展开。

编辑:我并不真正关心预处理器在宏扩展方面的行为。

【问题讨论】:

  • 您希望它扩展未包含的标头中存在的宏吗?
  • @Marcelo:我真的不在乎。

标签: c++ c include c-preprocessor


【解决方案1】:

将-nostdinc 用于gcc(或cpp)。

gcc ... -nostdinc ...

【讨论】:

  • 这涵盖标准包括但不包括例如boost 库包括我也不想扩展的。
  • 我对C++一无所知。祝你好运!
【解决方案2】:

在一般情况下,部分标题扩展是没有意义的。考虑以下示例:

#include <limits.h>

#if UINT_MAX > 0xffffffff
# include "fasthash_64.h"
#elif UINT_MAX == 0xffffffff
# include "hash.h"
#else
# error "int too small for hash implementation."
#endif

【讨论】:

  • 我想它应该单独留下条件部分。
  • @HighCommander4:所以你很高兴它没有扩展一些非系统的#includes?当然,如果非系统源代码中没有这样的条件逻辑,那么这不是问题。
  • 哦,现在我明白你的意思了。好吧,它可以在不触及条件逻辑的情况下扩展两个分支中的#include,对吧?
【解决方案3】:

这个怎么样?

#include <always_include.h>
#include <another_always_include.h>

#ifdef PART_2_INCLUDES
 #include <part2.h>
 #include <part2a.h>
#endif

#ifdef PART_3_INCLUDES
 #include <part3.h>
 #include <part3a.h>
#endif

...

然后,编译所有内容,gcc -DPART_2_INCLUDES -DPART_2_INCLUDES ... 或者,因为似乎通常所有内容都应该默认包含,而不包括某些项目是特殊情况,所以颠倒测试的意义:

#include <always_include.h>
#include <another_always_include.h>

#ifndef PART_2_INCLUDES_OMITTED
 #include <part2.h>
 #include <part2a.h>
#endif
...

【讨论】:

    【解决方案4】:

    C 预处理器不够聪明,无法自行完成。如果您只对 #include 感兴趣,您应该使用自己的工具(例如 Perl)来处理源文件,扩展您感兴趣的 #include 行并忽略其余部分。

    这个脚本用// Ignored:前缀无趣的标题行:

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    
    my @uninteresting = qw(iostream vector map);
    my $uninteresting = join '|', @uninteresting;
    
    while (<>) {
        s%(#include <(?:$uninteresting)>)%// Ignored $1%;
        print;
    }
    

    现在你可以这样做了:

    cat sourcefile.cpp | perl ignore-meh.pl | g++ -E
    

    如果你想变得非常花哨:

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    
    while (<>) {
        s%// Ignored (#include <[^>]+>)%$1%;
        print;
    }
    

    现在你可以这样做了:

    cat sourcefile.cpp | perl ignore-meh.pl | g++ -E | perl restore-meh.pl
    

    【讨论】:

      【解决方案5】:

      不想扩展的#include,可以换成$$$include之类的东西(总之,预处理器无法理解)。最好先将原始文件复制到临时文件中,然后运行gcc -E &lt;filename&gt;;。完成后,再次替换为原始源文件。

      这里唯一需要担心的是,您必须至少编辑一次源文件。但这可能没什么大不了的,因为您可以使用文本编辑器提供的功能。

      【讨论】:

      • 问题不只是我的 .cpp 文件包含库头文件,而且 .cpp 文件包含的许多项目头文件都会这样做,所以我必须更改很多文件...
      • 但这是唯一的出路!无论标题在预处理时出现错误,只需去替换它们或最好评论它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多