添加新运算符或类型时 #define 不是可识别的运算符或类型

Not a recognized operator or type when #define new is added

本文关键字:类型 运算符 识别 添加 #define      更新时间:2023-10-16

我正在尝试解决我的程序的一部分,它有一个 #define 新的。一切正常,直到我尝试创建一个覆盖新运算符的类模板,当我收到错误时:

C:Define_New_problemmain.cpp:18: error: expected type-specifier before 'dPushMemManFileLine'
C:Define_New_problemmain.cpp:18: error: expected ';' before 'dPushMemManFileLine'
C:Define_New_problemmain.cpp:21: error: expected ';' before '}' token
Process terminated with status 1 (0 minutes, 0 seconds)

使用MinGW。(简化的)代码如下:

#include <iostream>
#define new dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new
using namespace std;
static const int NUM_NEW_STACK_SIZE = 256;
static struct { const char* filename; unsigned int line; } g_NewStackMemDebug[NUM_NEW_STACK_SIZE];
static int g_CurStack = -1;
template <class T>
class mypair {
  private:
    int a, b;
  public:
    mypair (int first, int second)
      {a=first; b=second;}
    static void* operator new(size_t size)
    {
    }
};
int dPushMemManFileLine( const char* filename, unsigned int line )
{
    if(g_CurStack >= NUM_NEW_STACK_SIZE )
        return 0;
    g_CurStack++;
    g_NewStackMemDebug[g_CurStack].filename = filename;
    g_NewStackMemDebug[g_CurStack].line = line;
    return 0; // needed for the new passthrough trick
}
int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

没有人对如何解决这个问题有好主意?

不要。曾。#define .关键字。

拜托,只是不要。它只会制造问题。#define将定义单词的所有出现替换为您定义的内容,因此在扩展#define new后,运算符重载如下所示:

static void* operator dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new(size_t size)
    {
    }

呜....
那么问题当然仍然存在,你为什么要这样做?

我认为当您展开行中的newstatic void* operator new(size_t size) 错误变得非常明显:

class mypair {
    static void* operator dPushMemManFileLine( __FILE__, __LINE__ ) ? 0 : new(size_t size)
    { }
};

在关键字上使用#define是一种危险的游戏:)

如前所述,错误即将到来,因为您的#define new也在operator new处展开。

为了解决您的问题,我可以建议您尝试以下操作;这将有助于您避免使用宏:

//overload new with LINE & FILE and call the function inside
void* operator new (size_t size, const char *FILE, const unsigned int LINE)
{
  dPushMemManFileLine(FILE, LINE);
  return malloc(size);
}
//overload the default new operator and throw something vague    
void* operator new (size_t size)
{ 
  class BadNewUsed {} bad;
  throw bad;  // throw it; since we can't catch it at compile time
}

用法:

int *pi = new(__LINE__, __FILE__) int; // ok
double *pd = new double; // throws BadNewUsed out of your code,

您唯一需要付出的努力就是去纠正对new的调用,直到它不throw。您也可以使用简单的技术快速完成。只是做

#define new abcd // to get compilation error wherever new is present

现在去用NEW替换每个对new的调用。不要替换operator new实现。然后做,

#define NEW new( __FILE__, __LINE__)

并编译代码。请注意,此宏用法用于调试目的,并加快速度。我不建议在生产代码中使用它。

如果您不想使用像 NEW 这样的宏,也可以使用 templates 来实现这一点。

template<typename T>
T* NEW (const char* FILE, const unsigned int LINE)
{
  dPushMemManFileLine(FILE, LINE);
  return new T;  // can use default version or any overloaded version of 'new'
}

用法:

int *p = NEW<int>(__FILE__, __LINE__);