Macros C/C++;是否可以#取消定义由同一模式启动的一系列宏?

Macros C/C++;是否可以#取消定义由同一模式启动的一系列宏?,macros,c-preprocessor,Macros,C Preprocessor,我正在编写一个使用宏生成枚举的工具。完成后,我想取消所有这些宏的定义,但我还不知道所有的名称。Somes将在以后的开发中出现。所以我想做一个通用的undef,比如 #undef ENUM_* 可能吗?简化的宏如下所示: 首先 #define ENUM_VALUE(VALUE) VALUE, #define ENUM_STRING(STRING) #STRING, #define ENUM_GENERATE(NAME)\ namespace NAME {\ enum E

我正在编写一个使用宏生成枚举的工具。完成后,我想取消所有这些宏的定义,但我还不知道所有的名称。Somes将在以后的开发中出现。所以我想做一个通用的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开始的_


有没有一种简单的方法来取消对它们的定义?感谢

以下是评论中关于“基本宏”理念的详细建议:
它保留了一些已定义的宏,但保证任何使用都会被未定义的单个宏阻止。
也就是说,如果您取消对单个宏的定义,并且所有尝试使用该宏所代表的组中的一个宏的行为都会导致“未定义”错误,
或者在某些已定义的扩展中,这肯定会使编译器烦恼

// 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宏,将参数放在下面的一对大括号中,如示例
base\u 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.)

下面是评论中关于“基本宏观”理念的详细建议:
它保留了一些已定义的宏,但保证任何使用都会被未定义的单个宏阻止。
也就是说,如果您取消对单个宏的定义,并且所有尝试使用该宏所代表的组中的一个宏的行为都会导致“未定义”错误,
或者在某些已定义的扩展中,这肯定会使编译器烦恼

// 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宏,将参数放在下面的一对大括号中,如示例
base\u 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.)

你看过文件了吗?关于C标准中的6.10.3.5p1,有什么具体不清楚的地方?而且扩展代码不是C。注意:宏似乎没有做一些合理的事情,整个方法被设计破坏,最终在宏地狱中没有任何好处。不要太喜欢宏,特别是在C++中,你可以(也应该)使用核心语言构造。宏会使调试变得复杂,而任意地对宏进行定义(可能还会重新定义)会使事情变得更糟。不,我不知道你提到的文档。你有链接吗?关于宏,我知道它不是一个好工具。然而,它们允许创建一个同步系统,这对我来说很重要。模板没有。从这个意义上讲,“同步系统”是什么?要明确的是:如果一个同事在我的一个项目中提供这样的代码,我们会非常认真地讨论他的资格。你看过文档了吗?关于C标准中的6.10.3.5p1,有什么具体不清楚的地方?而且扩展代码不是C。注意:宏似乎没有做一些合理的事情,整个方法被设计破坏,最终在宏地狱中没有任何好处。不要太喜欢宏,特别是在C++中,你可以(也应该)使用核心语言构造。宏会使调试变得复杂,而任意地对宏进行定义(可能还会重新定义)会使事情变得更糟。不,我不知道你提到的文档。你有链接吗?关于宏,我知道它不是一个好工具。然而,它们允许创建一个同步系统,这对我来说很重要。模板没有。从这个意义上讲,“同步系统”是什么?需要明确的是:如果一个同事在我的一个项目中提供了这样的代码,我们会认真地讨论他的资格。注意:这个例子不是为了可编译而设计的,它是为了演示这个概念,通过预处理只运行编译器,如输出所示。我能理解这个想法
BASE\u BASE
是一座桥,桥在最后被摧毁(
unde
)。。。。。用法不是那么直观,但这是一个有趣的想法。谢谢。注意:这个例子不是为可编译而设计的,它是为了演示这个概念,从只运行编译器的预处理中可以看出,如输出所示。我能理解这个想法
BASE\u BASE
是一座桥,桥在最后被摧毁(
unde
)。。。。。用法不是那么直观,但这是一个有趣的想法。感谢