什么是偶然的宏观替代?

时间:2013-03-16 15:59:36

标签: c++ coding-style

什么是偶然的宏观替代?

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

为什么这是一个很好的规则,以及需要此规则的最小和最大函数有什么特别之处?

2 个答案:

答案 0 :(得分:8)

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

情况Vera ++的检查旨在防止在行为不端的系统标头(最着名的<windows.h> - 定义minmax宏,干扰应用程序定义的同名函数或即使使用标准库函数,例如std::min<T>std::max<T>std::numeric_limits<T>::min()。 (已知其他名称也会引起冲突。)

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

如果您控制了<windows.h>的加入,则可以在加入之前#define NOMINMAX,这将指示windows.h不要定义minmax宏。

答案 1 :(得分:0)

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