简体   繁体   English

预处理器宏作为其他宏的参数

[英]Preprocessor macros as parameters to other macros

The following C++ code compiles and works as the programmer intended on GCC (4.0.4) 以下C ++代码编译并作为GCC上的程序员工作(4.0.4)

#define FOO(x,y,z) ((x)*(y)*(z))
#define BAR(x) FOO(x,1)
#define BAZ 3,7

int main()
{
    return BAR(BAZ); /* interpreted as return ((3)*(7)*(1)); */
}

However, the macros cause an error on Microsoft Visual C++ Express 2010: 但是,宏在Microsoft Visual C ++ Express 2010上导致错误:

main.cpp(7): warning C4003: not enough actual parameters for macro 'FOO' main.cpp(7):警告C4003:宏'FOO'的实际参数不够
main.cpp(7): error C2059: syntax error : ')' main.cpp(7):错误C2059:语法错误:')'

The issue seems to be that the Microsoft compiler, while handling the BAR macro internally, does not expand the BAZ macro to parameters that could be used as two separate parameters to macro FOO. 问题似乎是Microsoft编译器在内部处理BAR宏时,不会将BAZ宏扩展为可用作宏FOO的两个独立参数的参数。

According to the standard, which compiler handles the situation correctly? 根据标准,哪个编译器正确处理了这种情况?

According to 16.3.4 of ISO/IEC 14882:2003 (C++ Stardard) macro expansion is performed as follows: 根据ISO / IEC 14882:2003(C ++ Stardard)的16.3.4,宏扩展如下进行:

  1. Macro invocation is replaced with the macro's replacement list (the body) where each parameter name (unless it is affected by # or ##) is substituted with a complete macro expansion of corresponding argument specified in macro invocation. 宏调用将替换为宏的替换列表(正文),其中每个参数名称(除非受#或##影响)将替换为宏调用中指定的相应参数的完整宏扩展。
  2. The result of step 1 is rescanned . 重新扫描步骤1的结果 If there are more macro invocations in it (except those already expanded getting the text under consideration), they are expanded according to the same procedure recursively. 如果其中有更多的宏调用(除了那些已经扩展获得正在考虑的文本的宏调用),它们将根据递归的相同过程进行扩展。

The sequence of steps for the code you specified is: 您指定的代码的步骤顺序如下:

  1. BAR(BAZ)
  2. FOO(3,7,1)
  3. ((3)*(7)*(1))

So GCC is right, and VC is not. 所以海湾合作委员会是对的,VC不是。 But the error which VC complains about is that FOO has 3 arguments and BAR specifies only 2 of them. 但VC抱怨的错误是FOO有3个参数而BAR只指定了2个参数。 VC apparently tries to catch errors as soon as possible and goes a bit too far in it. VC显然试图尽快发现错误并且有点太过分了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM