C / C ++是否可以#undef从同一个patern开始的一系列宏?

时间:2017-04-08 15:08:10

标签: macros c-preprocessor

我正在编写一个使用宏来生成枚举的工具。完成后,我想取消所有这些宏,但我还不知道所有的名字。有些人会在后来的发展中出现。所以我想制作一个通用的undef ... ...

#undef ENUM_*

这可能吗?简化的宏看起来像:

首先...

#define ENUM_VALUE(VALUE) VALUE,
#define ENUM_STRING(STRING) #STRING,

#define ENUM_GENERATE(NAME)\
    namespace NAME {\
        enum Enum: int { ENUM_##NAME(ENUM_VALUE) };\
        const char *Names[] = { ENUM_##NAME(ENUM_STRING) };\
    }\

然后为每个枚举我定义...

#define ENUM_MyEnum(VALUE)\
    VALUE(Value1)\
    VALUE(Value2)\
    VALUE(Value3)

ENUM_GENERATE(MyEnum)

它生成一个同步的枚举和字符串表,就像我声明了

一样
namespace MyEnum { 
    enum Enum: int { Value1, Value2, Value3 };
    const char *Names[] = { "Value1", "Value2", "Value3" };
}

唯一的问题是我以卡车装载的宏结束。有些人我还不知道,因为他们将在我新的枚举时被定义。但所有都是从ENUM _

开始的

有没有一种简单的方法可以解决所有这些问题?感谢

1 个答案:

答案 0 :(得分:2)

以下是"基本宏"的详细建议。评论的想法:
它留下了一些定义的宏,但保证任何使用都被未定义的单个宏阻止 即你unf这个单一的所有尝试使用它所代表的组中的一个宏导致一个" undefined"错误,
或者可能在一些定义的扩展中,但肯定会惹恼编译器。

// Infrastructure
#define BASE_BASE(ParWhich) BASED_##ParWhich

// Secondary infrastructure, needed for supporting parameterised macros.
#define BASE_NOPAR(ParWhich) BASE_BASE(ParWhich)
#define BASE_ONEPAR(ParWhich, ParOne) BASE_BASE(ParWhich)(ParOne)

// Potentially many macros being defined in a slightly "get-used-to" manner.
#define BASED_A Hello
#define BASED_B(ParWhat) ParWhat
#define BASED_C(ParWord) ParWord

// Example line, to be expanded by prepro with defined macro BASE_BASE.
BASE_NOPAR(A) BASE_ONEPAR(B,PreProcessor) BASE_NOPAR(B)(World.)


// The one line which should lead to compiler errors for any use of one of the macros.
#undef BASE_BASE

// Same example again.
BASE_NOPAR(A) BASE_ONEPAR(B,PreProcessor) BASE_NOPAR(B)(World.)

// Not necessary, just to make sure and to make readable prepro-output.
#define BASE_BASE(ParIgnore) Compiler, please fail here!

// Same example again.
BASE_NOPAR(A) BASE_ONEPAR(B,PreProcessor) BASE_NOPAR(B)(World.)

使用带参数的基本宏和以下对中的参数括号,如示例BASE_NOPAR(C)(World.)中所做 不应该在任何地方直接在代码中完成;因为在我看来, 很快变成维护噩梦。 即它应该在一个核心的核心"如另有说明的那样 不会想要任何类似的代码。

输出:

>gcc -E -P BaseMacro.c
Hello PreProcessor World.
BASE_BASE(A) BASE_BASE(B)(PreProcessor) BASE_BASE(B)(World.)
Compiler, please fail here! Compiler, please fail here!(PreProcessor) Compiler, please fail here!(World.) Compiler, please fail here!(World.)