C++ 微软C++;和g++;预处理器行为差异

C++ 微软C++;和g++;预处理器行为差异,c++,g++,preprocessor,C++,G++,Preprocessor,我有这样的测试程序: #ifdef _WINDOWS #include "stdafx.h" #endif #include "string.h" #include "stdio.h" #define ENTYPEDATA_STEP_3_D 3 #define ENTYPEDATA_STEP_10_2F 10 #define ENTYPEDATA_STEP_HEADER_4_D (4) #define UINT unsigned int #define SBUF_HEADER_INIT(

我有这样的测试程序:

#ifdef _WINDOWS
#include "stdafx.h"
#endif
#include "string.h"
#include "stdio.h"


#define ENTYPEDATA_STEP_3_D 3
#define ENTYPEDATA_STEP_10_2F 10
#define ENTYPEDATA_STEP_HEADER_4_D (4)
#define UINT unsigned int


#define SBUF_HEADER_INIT(n, data, m)\
 sprintf(cTmpTb,"%d",##m);\
 strcpy(cTmpTf,"%");\
 strcat(cTmpTf,cTmpTb);\
 strcat(cTmpTf,"d");\
 sprintf(TmpHeaderBuf,cTmpTf,data);\
 strcpy(this->m_pBufs##n,TmpHeaderBuf);

class m_test {
    private:
     char TmpHeaderBuf[ENTYPEDATA_STEP_HEADER_4_D+1];
     char cTmpTb[50];
     char cTmpTf[50];
     char TmpBuf[ENTYPEDATA_STEP_10_2F+1];

    char *m_pBufs0;
    char *m_pBufs5;

    public:
        m_test();
        ~m_test();
};


int main(int argc, char* argv[]){
    m_test l_test;
    return 0;
}


m_test::m_test(){
    m_pBufs0= new char[20];
    m_pBufs5= new char[20];

    SBUF_HEADER_INIT(5, (UINT)(ENTYPEDATA_STEP_3_D), ENTYPEDATA_STEP_HEADER_4_D)
}

m_test::~m_test(){
    delete m_pBufs0;
    delete m_pBufs5;
}

在微软Visual StudioC++ + VER 6中编译此文件,没有任何错误,但在G+7.7.0下,我对宏的错误:

$g++ test_macro.cpp
test_macro.cpp:16:21: error: pasting "," and "ENTYPEDATA_STEP_HEADER_4_D" does not give a valid preprocessing token
  sprintf(cTmpTb,"%d",##m);\
                     ^
test_macro.cpp:51:5: note: in expansion of macro ‘SBUF_HEADER_INIT’
     SBUF_HEADER_INIT(5, (UINT)(ENTYPEDATA_STEP_3_D), ENTYPEDATA_STEP_HEADER_4_D)
     ^~~~~~~~~~~~~~~~
我不知道如何在没有完全分离成一些简单宏的情况下修复它。 请帮忙

UPD: 宏

#define SBUF_HEADER_INIT(N, data, MD)\
 sprintf(cTmpTb,"%d",MD);\
 strcpy(cTmpTf,"%");\
 strcat(cTmpTf,cTmpTb);\
 strcat(cTmpTf,"d");\
 sprintf(TmpHeaderBuf,cTmpTf,data);\
 strcpy(this->m_pBufs##N,TmpHeaderBuf);
工作完美

GCC是正确的

你只需要
m

您正在尝试在没有意义的情况下执行令牌连接


VisualStudio6无论如何都是允许的(VS2019也是如此)。从技术上讲,您的方法具有未定义的行为,因此任何结果实际上都是“正确的”,但GCC的方法最有意义。请注意,如果我受到诱惑,我甚至不会在那种环境中依赖它。

类似:仅供参考:VS 2019似乎也接受它……它将它视为
(4)
,这相当令人惊讶。@ChrisMM:Figures!