这是我第一次在阅读Mike Banahan撰写的C书时遇到“重新定义宏观”的概念(Section 7.3.2)。但是从我在下面给出的段落中可以看出,除了严格限制之外,重新定义除了重复同样的事情之外根本不会有任何用处。当然,我的理解是错误的,作者必须有一个观点。那么请您简单地解释一下C中宏的确切重新定义是什么,以及在我们遵守给出的限制和规则后,我们究竟能做些什么来重新定义它。示例代码将非常有用。谢谢。
提取的文字如下:
标准允许随时重新定义任何类型的宏, 使用另一个#define,前提是没有任何尝试 更改宏的类型和令牌组成的两个 原始定义和重新定义的数量相同, 订购,拼写和使用白色空间。在这种情况下全白 空间被认为是平等的,所以这是正确的:
#define XXX abc/*comment*/def hij #define XXX abc def hij
因为评论是一种空白形式。两种情况的标记序列(w-s代表空格标记)是:
# w-s define w-s XXX w-s abc w-s def w-s hij w-s
答案 0 :(得分:2)
实际上,您通常不希望重新定义宏。大部分时间都是由于名称冲突而发生的(两段代码定义了一个具有相同名称的宏,可能会也可能不会执行相同的操作)。您引用的规则说,在两个定义之间的唯一区别是空格的情况下,允许重新定义。在这种情况下,两个定义都会做同样的事情。在任何其他情况下,所有投注都已关闭。
例如,一个常见的事情是最多两个数字。如果你写一个MAX宏,一种方法是:
// ASSUME: multiple references to macro parameters do not cause problems
#define MAX(a, b) ((a) > (b) ? (a) : (b))
由于MAX
是返回最多两个数字的宏的明显名称,因此很有可能其他人可能具有相同的想法并且还定义了MAX
宏。如果它们恰好以与您完全相同的方式定义它,编译器将接受多个定义,因为它们执行相同的操作(尽管一些编译器仍然会对此进行警告)。
如果有人以不同方式定义MAX
,编译器将在重新定义时抛出错误。抛出错误是件好事。如果编译器总是选择第一个或最后一个定义,程序员很可能不会意识到将使用与他们预期不同的宏。
如果您需要解决宏的多个定义(例如,两个不同的第三方库选择相同的名称),您可以使用#ifdef
检查宏是否已定义并且#undef
为"取消定义"第一个定义,如果你想要第二个。这种解决方案通常很脆弱。如果您有选择,避免名称冲突是更好的解决方案。