Не распознанный оператор или тип при добавлении #define new - PullRequest
1 голос
/ 10 мая 2011

Я пытаюсь решить часть моей программы, в которой есть #define new.Все работает хорошо, пока я не попытаюсь создать шаблон класса, который переопределяет новый оператор, когда я получаю ошибки:

C:\Define_New_problem\main.cpp:18: error: expected type-specifier before 'dPushMemManFileLine'
C:\Define_New_problem\main.cpp:18: error: expected ';' before 'dPushMemManFileLine'
C:\Define_New_problem\main.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;
}

Кто-нибудь знает, как решить эту проблему?

Ответы [ 3 ]

9 голосов
/ 10 мая 2011

Don't.Ever. #define .KEYWORDS.

Пожалуйста, просто не . Это только создает проблему. A #define заменяет все вхождения определенного слова тем, что вы его определили, поэтому после расширения #define 'd new перегрузка оператора выглядит следующим образом:

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

Uuups ....
Тогда, конечно, остается вопрос, почему ты это сделал?

3 голосов
/ 10 мая 2011

Я думаю, что при расширении new в строке static void* operator new(size_t size) ошибка становится довольно очевидной:

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

Использование #define для ключевых слов - опасная игра:)

1 голос
/ 10 мая 2011

Как уже упоминалось, ошибка наступает, потому что ваш #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__)

И скомпилируйте код. Обратите внимание, что этот макрос используется для вашей цели отладки и ускоряет работу. Я не рекомендую его использовать в рабочем коде.

Вы можете добиться этого, используя templates, даже если вы не хотите использовать макросы, такие как NEW.

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__);
...