7

什么是意外宏替换?

Vera++ C++ linter 中,规则 T016 规定:

对 min 和 max 函数的调用应防止意外宏替换。

x = max(y, z); // wrong, vulnerable to accidental macro substitution

x = (max)(y, z); // OK

x = max BOOST_PREVENT_MACRO_SUBSTITUTION (y, z); // OK

为什么这是一条好规则,需要这条规则的 min 和 max 函数有什么特别之处?

4

2 回答 2

8

意外宏替换是无意使用名称与函数冲突的宏。

Vera++ 的检查旨在防止出现行为不端的系统头文件(最著名的是<windows.h>)定义minmax宏会干扰应用程序定义的同名函数,甚至干扰标准库函数,如std::min<T>std::max<T>std::numeric_limits<T>::min(). (已知其他名称也会引起冲突。)

由于宏不支持命名空间,因此调用函数 as无济于事,因为预处理器仍会对其进行扩展。要解决此问题,必须将此类函数调用为,这将阻止宏扩展,前提是它被定义为,通常是和的情况。另一个可用的选项是在使用之前,但在包含行为不端的标头之后。Boost 提供了自己的替代预防标记,尽管它的自我描述性被它引入的混乱所抵消。std::min(...)min(function)(args...)#define function(arg1, arg2) ...minmax#undef

如果您控制 的包含<windows.h>,您也可以#define NOMINMAX在它包含之前,这将指示windows.h不要定义minandmax宏。

于 2013-03-16T16:05:32.713 回答
0

问题是讨厌的库(或愚蠢的程序员)通常会定义您可能没想到的 max 和 min 宏。如果您的代码假设评估将由一个不错的函数完成,那么您将得到不正确的结果(甚至是未定义的行为)。linter 指出这一点很有帮助,除非你真的确定你知道你正在使用的所有包含定义的所有宏,否则不要冒与这些常见宏名称发生冲突的风险更安全。

于 2013-03-16T16:07:29.803 回答