C++ 在复杂情况下如何执行宏替换?

C++ 在复杂情况下如何执行宏替换?,c++,c,c-preprocessor,C++,C,C Preprocessor,考虑以下示例代码 #define T(q) L##q #define A(p) T("x" T(#p)) wchar_t w[] = A(a); 这个代码格式正确吗?w的值是多少?行为是否在 c>强>和C++中有所不同?在C++0x中它不同吗 我浏览了C++03标准,在我看来,代码应该是有效的,w的值应为L“xa” 调用A,对其进行处理产生pp序列T(“x”T(“A”)) 调用T,产生L##x“T(“a”),这反过来产生L“x”T(“a”) 调用T,产生L“x”L“a” 对吗?EDG和Clan

考虑以下示例代码

#define T(q) L##q
#define A(p) T("x" T(#p))
wchar_t w[] = A(a);
这个代码格式正确吗?
w
的值是多少?行为是否在<强> c>强>和C++中有所不同?在C++0x中它不同吗

我浏览了C++03标准,在我看来,代码应该是有效的,
w
的值应为
L“xa”

  • 调用
    A
    ,对其进行处理产生pp序列
    T(“x”T(“A”))
  • 调用
    T
    ,产生
    L##x“T(“a”)
    ,这反过来产生
    L“x”T(“a”)
  • 调用
    T
    ,产生
    L“x”L“a”
  • 对吗?EDG和Clang都不接受这个代码段,MSVC 9编译得很好。

    g++扩展到

    L"x" T("a")
    
    宏不能是递归的,它们只能在一次快照中预处理,因此
    T(#p)
    不会再次展开。如果需要
    L“xa”
    ,则可以执行以下操作:

    #define A(p) T("x")#p
    #define T(q) L##q
    

    (它实际上是
    L“x”a

    我还以为它扩展到
    L“x”T(“a”)
    。在宏的结果标记序列中,不再考虑替换宏的名称。因此,<代码> T(“A”)< /代码>不再被取代——步骤<代码> 3 < /COD>不是。这篇文章解释了宏扩展算法OH,对,我没有考虑宏被扩展两次的事实…@ LITB,也许你想把评论粘贴到答案中去?我为此提供了25个代表:)请注意,MSVC不会接受
    L“x”“a”
    作为有效的字符串文本。因此,OP仍将保留一个
    a()
    宏,该宏在一个编译器上工作,而不是在另一个编译器上工作<代码>#定义一个(p)T(“x”)T(#p)将扩展到
    L“x”L“A”
    ,并将在两个编译器上工作。