根据standard宏的重新定义,在以下情况下禁止使用#undef
:
但以下重新定义无效:
#define OBJ_LIKE (0) // different token sequence
#define OBJ_LIKE (1 - 1) // different whitespace
字符串
同时,对于之前根本没有定义的宏,允许使用#undef
:
如果指定的标识符当前未定义为宏名,则将忽略该标识符。
我感兴趣的是这样做的理由是什么,即禁止在中间没有#undef
的情况下重新定义?一些编译器优化的目的还是什么?
3条答案
按热度按时间0sgqnhkj1#
这是不允许的,因为默默地重新定义一个宏来表示其他东西可能是一个错误。考虑下面的例子:
个字符
这个Assert现在成功了,因为
<cassert>
中的assert
重新定义了Assert是什么。一般来说,重新定义事物可能会产生一些后果:请记住,
#include
的顺序很重要,每个宏都可以通过这种方式溢出到任何其他头中。与宏重新定义相关的错误可能很难跟踪。如果你想改变一个宏名的用途,你可以先
#undef
它。yzxexxkh2#
因为它继承自C。
ISO/IEC 9899:1990 §6.8.3(AKA C90)包含类似措辞:
如果第二个定义是一个类似于对象的宏定义,并且两个替换列表是相同的,那么当前定义为一个没有使用lparen的宏(类似于对象的宏)的标识符可以由另一个
#define
预处理指令重新定义。当前使用lparen定义为宏的标识符(类似 * 函数的 * 宏)可以由另一个
#define
预处理指令重新定义,只要第二个定义是类似函数的宏定义,具有相同的参数数量和拼写,并且两个替换列表相同。再看看WG 14(https://www.open-std.org/jtc1/sc22/wg14/www/docs/n802.pdf)《国际标准-程序设计语言- C的基本原理》§6.8.3产生的N802,理由是:
委员会希望不允许“有害的重新定义”,
(in header1.h)
字符串
(in header. h)
型
这显然是程序中严重错误的诱因。然而,仍然存在“良性重新定义”的问题,例如(在header1.h中)
型
(in header. h)
型
委员会得出结论认为,在定义相同的情况下,允许良性重定义可以更好地服务于安全编程实践。这允许独立的标头指定他们对每个感兴趣的符号的正确值的理解,只有在定义不同时才会生成诊断。
因此,鼓励“良性”的重新定义,替代方案可能是这样的:
型
#define SPEED_OF_LIGHT 299792458
会在另一个header以不同的方式定义它时生成一个警告。#undef
也是类似的情况。第6.8.3.5节给出的理由是:它明确允许
#undef
一个没有当前定义的宏。这个功能可以和标准库一起使用(见§7.1.8)。其中C99的§7.1.8/C90的§7.1.7规定:
使用
#undef
删除任何宏定义也将确保引用实际函数。例如,一个标准的库头可能有
double abs(double);
和#define abs(x) _BUILTIN_abs(x)
,而#undef abs
是法律的,允许您确保abs
引用真正的函数。当然,这并不适用于C++,在C++中标准库函数不能是宏。但另一个理由(“明确允许
#undef
一个没有当前定义的宏”)仍然适用,即“委员会是这么说的”。zf9nrax13#
我们不能检查MACRO定义,我们只能检查是否定义了MACRO。
所以,如果你想检查
#undef
只在定义的MACRO上完成,你可以自己检查:字符串
对于重新定义宏观,
型