c - C 中宏的重新定义到底是什么?考虑到这么多限制,有什么意义呢?

标签 c macros redefinition

这是我在阅读Mike Banahan 的C 书时第一次遇到“重新定义宏”的概念(Section 7.3.2) .但是从我可以从那里给出的以下段落中可以判断的情况来看,鉴于严格的限制,重新定义除了重复相同的事情之外根本没有任何用处。当然我的理解是错误的,作者一定是有道理的。那么能否请您简单解释一下C语言中宏的重定义到底是什么,以及在我们遵守为此给出的限制和规则后,我们究竟可以做什么来重定义它。示例代码将非常有帮助。谢谢。

提取的文本如下:

The Standard allows either type of macro to be redefined at any time, using another # define, provided that there isn't any attempt to change the type of the macro and that the tokens making up both the original definition and the redefinition are identical in number, ordering, spelling and use of white space. In this context all white space is considered equal, so this would be correct:

#define XXX abc/*comment*/def hij
#define XXX abc def hij 

because comment is a form of white space. The token sequence for both cases (w-s stands for a white-space token) is:

# w-s define w-s XXX w-s abc w-s def w-s hij w-s

最佳答案

实际上,您通常不想重新定义宏。大多数情况下,它是由于名称冲突而发生的(两段代码定义了一个具有相同名称的宏,可能会或可能不会做同样的事情)。您引用的规则说,在两个定义之间的唯一区别是空格的情况下,允许重新定义。在那种情况下,两个定义将做同样的事情。在任何其他情况下,所有的赌注都没有了。

例如,通常需要的是两个数字中的最大值。如果您编写 MAX 宏,一种方法是:

// ASSUME: multiple references to macro parameters do not cause problems
#define MAX(a, b) ((a) > (b) ? (a) : (b))

由于 MAX 是返回两个数字中最大值的宏的明显名称,因此其他人很可能有相同的想法并且也定义了 MAX 宏。如果他们碰巧以与您完全相同的方式定义它,编译器将接受多个定义,因为它们做同样的事情(尽管一些编译器仍会对此发出警告)。

如果有人对 MAX 进行了不同的定义,编译器将在重新定义时抛出错误。抛出错误是一件好事。如果编译器总是选择第一个或最后一个定义,程序员很可能不会意识到将使用与他们预期不同的宏。

如果您需要解决宏的多个定义(例如,两个不同的第 3 方库选择相同的名称),您可以使用 #ifdef 检查宏是否已经定义并且 #undef 如果您想要第二个定义,则“取消定义”第一个定义。这样的解决方案通常很脆弱。如果您有选择,避免名称冲突是更好的解决方案。

关于c - C 中宏的重新定义到底是什么?考虑到这么多限制,有什么意义呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26087602/

相关文章:

C指向结构中数组的指针传递给函数

c++ - 使用宏获取函数指针的函数名称 # 不起作用

macros - 如何在 Racket 中使用宏重命名过程?

c++ - 为什么将 1 个头文件包含到两个 CPP 文件中不会导致重新定义错误?

c - 从简单的浮点计算中得到错误的输出

c - 如何让我的代码正确打印二进制?

c - 如何在 Windows 10 中使用 Code::Blocks 16.01 计算 -O3 的时钟周期?

c - 使用 C 预处理器进行嵌套宏迭代

c++ - Arduino类重新定义错误

C++ 重新定义 - 头文件