对C或C++源文件进行部分预处理

Partially preprocess a C or C++ source file?

本文关键字:行部 预处理 源文件 C++      更新时间:2023-10-16

是否有部分预处理C或C++源文件的方法?我所说的"部分预处理"是指扩展一些但不是全部的#include指令。例如,我想扩展指向我的项目头的#includes,而不是指向其他库的头的#contains。

我试图通过运行gcc -E来做到这一点,只使用项目头的-I标志,而不使用库的-I标志,但这不起作用,因为gcc在遇到#include时会出错,它无法扩展。

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

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

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

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

这个怎么样?:

#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
...

-nostdinc用于gcc(或cpp)。

gcc ... -nostdinc ...

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

#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