San*_*ich 2 c macros c-preprocessor
在许多地方,我在定义相同的宏之前看到了undefine宏的用法.例如:
#undef FORMULA
#ifdef SOMETHING
#define FORMULA 1
#else
#define FORMULA 2
#endif
Run Code Online (Sandbox Code Playgroud)
用的是什么#undefine FORMULA?我可能猜测它处理之前已定义宏的情况.但新的定义是否超越旧定义?谢谢!
当前定义的宏名称不能使用不同的定义重新定义(请参见下文),因此#undef允许使用不同的定义重新定义宏名称.
这是相关的法律术语:
C和C++标准(相同的措辞):
宏定义持续(独立于块结构),直到遇到相应的#undef指令或(如果没有遇到)直到预处理转换单元结束.
措辞略有不同,含义相同:
C标准(N1256),§6.10.3/ 2:
当前定义为类似对象的宏的标识符不应由另一个#define预处理指令重新定义,除非第二个定义是类似于对象的宏定义,并且两个替换列表是相同.同样,当前定义为类似函数宏的标识符不应由另一个#define 预处理指令重新定义,除非第二个定义是具有相同数量和参数拼写的类函数宏定义,并且两个替换列表相同.C++标准(N3337)§16.3/ 2
当前定义为类似对象的宏的标识符可以由另一个#define预处理指令重新定义,前提是第二个定义是类似于对象的宏定义,并且两个替换列表相同,否则程序是不正确的.同样,当前定义为类似函数的宏的标识符可以由另一个#define预处理指令重新定义,前提是第二个定义是具有相同数量和参数拼写的类函数宏定义,并且两个替换列表相同,否则该计划是不正确的.
两个标准中的措辞相同:
当且仅当两者中的预处理标记具有相同的数字,排序,拼写和空白分隔时,两个替换列表是相同的,其中所有空白分隔被认为是相同的.
所以:
#define X(y) (y+1)
#define X(z) (z+1) // ill-formed, not identical
Run Code Online (Sandbox Code Playgroud)
恕我直言,#undef由于预处理器宏的范围规则,使用通常是危险的.我更喜欢从预处理器获得警告或错误,并提出一个不同的预处理器宏,而不是让一些翻译单元默默地接受一个错误的宏定义,这会在程序中引入一个错误.考虑:
// header1.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x400
// header2.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x410
Run Code Online (Sandbox Code Playgroud)
并有一个翻译单位#include两个标题.没有警告,可能不是预期的结果.