C++ 是否有基于已定义/未定义值消除#ifdef块的C预处理器? 原始问题

C++ 是否有基于已定义/未定义值消除#ifdef块的C预处理器? 原始问题,c++,c,preprocessor,C++,C,Preprocessor,我想要的不是一个标准的C预处理器,而是它的一个变体,它可以接受来自某个地方的命令行,可能是通过-DNAME1和-UNAME2选项,一个定义宏的规范,然后消除死代码 通过一些例子,可能更容易理解我的目的: #ifdef NAME1 #define ALBUQUERQUE "ambidextrous" #else #define PHANTASMAGORIA "ghostly" #endif 如果命令与'-DNAME1'一起运行,则输出为: #define ALBUQUERQUE "ambidex

我想要的不是一个标准的C预处理器,而是它的一个变体,它可以接受来自某个地方的命令行,可能是通过-DNAME1和-UNAME2选项,一个定义宏的规范,然后消除死代码

通过一些例子,可能更容易理解我的目的:

#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif
如果命令与'-DNAME1'一起运行,则输出为:

#define ALBUQUERQUE "ambidextrous"
#define PHANTASMAGORIA "ghostly"
如果命令与'-UNAME1'一起运行,则输出为:

#define ALBUQUERQUE "ambidextrous"
#define PHANTASMAGORIA "ghostly"
如果命令在运行时没有使用这两个选项,则输出将与输入相同

这是一个简单的案例——我希望代码也能处理更复杂的案例

用一个真实但仍然简单的例子来说明:

#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void    VOID;
#endif /* PLATFORM1 */
typedef void *  VOIDPTR;
#else
typedef mint     VOID;
typedef char *  VOIDPTR;
#endif /* USE_VOID */
我想用
-DUSE\u VOID-UPLATFORM1
运行命令并获得输出:

#undef VOID
typedef void    VOID;
typedef void *  VOIDPTR;
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
另一个例子:

#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
理想情况下,我希望使用
-UOLDUNIX
运行并获得输出:

#undef VOID
typedef void    VOID;
typedef void *  VOIDPTR;
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
这可能会给我带来好运

动机:大型、古老的代码库,包含大量条件代码。许多条件不再适用——例如,旧的UNIX平台已不再制造,也不再受支持,因此不需要在代码中引用它。其他条件总是正确的。例如,功能是通过条件编译添加的,这样一个单一版本的代码既可以用于功能不可用的较旧版本的软件,也可以用于功能可用的较新版本(或多或少)。最终,没有该功能的旧版本将不再受支持-所有内容都使用该功能-因此应删除该功能是否存在的条件,并删除“当功能不存在时”代码。我希望有一个自动完成这项工作的工具,因为它比手动完成这项工作更快、更可靠(当代码库包含21500个源文件时,这一点非常关键)

(该工具的一个非常聪明的版本可能会读取
#include
'd文件,以确定控制宏(由命令行上的-d或-U指定)是否定义在这些文件中。我不确定除了作为备份诊断之外,这是否真的有用。不过,无论它做什么,伪预处理器都不能扩展macr操作系统或包含文件。输出源代码必须与输入代码类似,但通常比输入代码简单。)

状态报告(一年后) 经过一年的使用,我对所选答案推荐的“”非常满意。它还没有犯错误,我也不认为会犯错误。我对它唯一的质疑是风格。给出如下输入:

#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
并使用'-UC'运行(从未定义C),输出为:

#if defined(A) && defined(B) || defined(D) && defined(E)
这在技术上是正确的,因为“&&”比“| |”绑定得更紧,但这会引起混淆。我更希望它在“&&”条件集周围包含括号,如原始:

#if (defined(A) && defined(B)) || (defined(D) && defined(E))
然而,考虑到我必须处理的一些代码的晦涩难懂,这是一种强烈的赞美;它对我来说是很有价值的工具


新来的孩子
在检查了上述信息中包含的URL之后,我看到了(正如预测的那样)有一个新的程序名为“that is the继任者”,它是“sunifdef”。它在SourceForge上提供,从2010年1月开始。我将查看它…今年晚些时候,或者明年,或者某个时候,或者永远不会有更多的报告。

我对C一无所知,但听起来你在寻找类似的东西。请注意,它是hasn自2000年以来没有更新过,但有一个后继版本名为。

我对C一无所知,但听起来你在寻找类似的东西。请注意,它自2000年以来没有更新过,但有一个后继版本名为。

大约在2004年,我写了一个工具,完全满足了你的需求。我从未抽出时间发布过正在使用该工具,但可以在此处找到代码:

(这是dsl链接)


它大约有1.7k行,实现了足够多的C语法,可以使用bison和flex解析预处理器语句、注释和字符串。

大约2004年,我编写了一个工具,完全满足了您的需要。我从未分发过该工具,但代码可以在这里找到:

(这是dsl链接)


它大约有1.7k行,实现了足够多的C语法,可以使用bison和flex解析预处理器语句、注释和字符串。

我几年前就用unifdef解决了您描述的问题,它工作得很好。即使它自2000年以来没有更新过,预处理器ifdefs的语法自2000年以来也没有实质性的变化n、 因此,我希望它仍能满足您的要求。我想可能会有一些编译问题,尽管这些包看起来是最新的


我从未使用过sunifdef,所以我不能直接对它发表评论。

几年前,我使用unifdef只是为了解决您描述的那种问题,它工作得很好。即使它自2000年以来没有更新过,预处理器ifdefs的语法从那时起就没有实质性的变化,所以我希望它仍能满足您的要求。我想可能会有一些变化编译问题,尽管包看起来是最新的


我从未使用过sunifdef,所以我不能直接对它发表评论。

如果您需要类似于预处理器的东西,灵活的解决方案是(来自boost)。它是一个库,旨在构建类似于C预处理器的工具(包括C++03和C++0x预处理器).由于它是一个库,您可以连接到它的输入和输出代码。

如果您需要类似于预处理器的东西,灵活的解决方案是(来自boost)。它是一个库,旨在构建类似C预处理器的工具(包括C++03和C++0x预处理器等)。由于它是一个库,您可以连接到它的输入和输出代码。

您也可以尝试使用此工具

像这样的东西