Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
预处理器宏作为其他宏的参数 < >下面的C++代码编译和工作在GCC(4.0.4)上的程序员 但是,宏在微软Visual C++快速表2010:上会引起错误。_C++_Macros_C Preprocessor_Legacy Code_Visual Studio Macros - Fatal编程技术网

预处理器宏作为其他宏的参数 < >下面的C++代码编译和工作在GCC(4.0.4)上的程序员 但是,宏在微软Visual C++快速表2010:上会引起错误。

预处理器宏作为其他宏的参数 < >下面的C++代码编译和工作在GCC(4.0.4)上的程序员 但是,宏在微软Visual C++快速表2010:上会引起错误。,c++,macros,c-preprocessor,legacy-code,visual-studio-macros,C++,Macros,C Preprocessor,Legacy Code,Visual Studio Macros,main.cpp(7):警告C4003:宏“FOO”的实际参数不足 main.cpp(7):错误C2059:语法错误:')' 问题似乎在于,Microsoft编译器在内部处理BAR宏时,没有将BAZ宏扩展到可以用作宏FOO的两个单独参数的参数 根据标准,哪个编译器正确处理这种情况?根据ISO/IEC 14882:2003(C++标准)的16.3.4,宏扩展执行如下: 宏调用被替换为宏的替换列表(主体),其中每个参数名(除非受#或###影响)被替换为宏调用中指定的相应参数的完整宏展开 重新扫描步骤

main.cpp(7):警告C4003:宏“FOO”的实际参数不足
main.cpp(7):错误C2059:语法错误:')'

问题似乎在于,Microsoft编译器在内部处理BAR宏时,没有将BAZ宏扩展到可以用作宏FOO的两个单独参数的参数


根据标准,哪个编译器正确处理这种情况?

根据ISO/IEC 14882:2003(C++标准)的16.3.4,宏扩展执行如下:

  • 宏调用被替换为宏的替换列表(主体),其中每个参数名(除非受#或###影响)被替换为宏调用中指定的相应参数的完整宏展开
  • 重新扫描步骤1的结果。如果其中有更多的宏调用(除了那些已经展开并正在考虑的文本),它们将根据相同的过程递归展开
  • 指定代码的步骤顺序为:

  • BAR(BAZ)
  • FOO(3,7,1)
  • ((3)*(7)*(1))

  • 所以GCC是对的,VC不是。但是VC抱怨的错误是,
    FOO
    有3个参数,
    BAR
    只指定了其中的2个。VC显然试图尽快发现错误,但做得有点过火。

    似乎你真正想要的是。@leftaroundabout似乎不是…@iammilind:标准第16章缺少什么?这怎么不是一个“真正的”标准呢?@iammilind当然是这样。它的设计允许在实现中有一定的回旋余地,某些涉及标记粘贴的操作会导致未定义的行为,但这里的情况并非如此。(通常,在存在未定义行为的情况下,g++会发出错误信号,大多数其他编译器都会接受它。)@CharlesBaily,你是对的。删除评论(登录到PC后)。我不明白您给出的算法如何对应GCC行为。如果我读对了,算法如下:
    BAR(BAZ)
    是对
    BAR
    的调用,带有参数
    BAZ
    ,因此被替换为
    FOO(BAZ,1)
    。现在将对其进行重新扫描。它找到的第一个宏是
    FOO
    ,因此现在它尝试用参数
    BAZ
    1
    展开
    FOO
    。这是不够的参数,因此预处理失败。当扫描
    BAR(BAZ)
    时,为什么重新扫描
    FOO(BAZ,1)
    首先展开
    BAZ
    ,首先展开
    BAR
    ?感谢您的清晰完整的解释。我学到了很多。
    #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)); */
    }