【问题标题】:Microsoft C++ and g++ preprocessor behavior differenceMicrosoft C++ 和 g++ 预处理器行为差异
【发布时间】:2020-01-02 18:39:02
【问题描述】:

我有这样的测试程序:

#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;
}

在 Microsoft Visual Studio C++ 版本 6 下,此文件编译时没有任何错误,但在 g++ 7.4.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)
     ^~~~~~~~~~~~~~~~

如果不完全分离成一些简单的宏,我不明白如何修复它。 请帮忙。

更新: 宏

#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);

完美运行

【问题讨论】:

标签: c++ g++ preprocessor


【解决方案1】:

GCC 是正确的。

你只想要m

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

Visual Studio 6 无论如何都允许这样做(VS 2019 也是如此)。从技术上讲,您的方法具有未定义的行为,因此任何结果实际上都是“正确的”,但 GCC 最有意义。请注意Visual Studio's behaviour is undocumented,所以如果我受到诱惑,我什至不会在那种环境中依赖它。

【讨论】:

  • 仅供参考:VS 2019 似乎也接受了它……它把它当作(4) 对待,这相当令人惊讶。
  • @ChrisMM:数字!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多