замена нового на макро конфликты с размещением нового - PullRequest
7 голосов
/ 14 февраля 2011

У меня огромное приложение (несколько миллионов LOC и десятки тысяч файлов), и я пытаюсь использовать отладочный crt для обнаружения утечек памяти. Я пытаюсь макроизображать новое так:

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifndef NEW_DEBUG
#define NEW_DEBUG new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new NEW_DEBUG
#endif

Теперь мое приложение настолько велико, что для меня, в идеале, я бы поместил это в заголовочный файл и специально включил в десятки тысяч файлов CPP. Не веселая задача. Поэтому я попытался поместить это в общий заголовочный файл в нашем SDK, который будет включен в каждую переводческую единицу.

Проблема, с которой я сталкиваюсь, заключается в том, что она конфликтует с некоторыми заголовочными файлами STL, и компилятор выдает ошибки при использовании размещения new. Я могу изменить это в своем собственном коде, используя прагмы и отключив новый макрос. Не проблема там. Это заголовочные файлы STL, которые используют новое размещение, я не могу изменить.

Я нашел обходной путь , переставив директивы include в файлах cpp. Например:

// doesn't compile
#include "new_redirect.h"
#include <map> // for instance

// does compile
#include <map> // for instance
#include "new_redirect.h"

Но это трудный обходной путь, потому что мне снова нужно изменить тысячи файлов и убедиться, что их заголовки STL включены перед чем-либо еще. Ирония в том, что я создал приложение hello world, чтобы специально протестировать эту проблему: и приложение hello world скомпилировано нормально. Но мое массивное приложение не обходится без этого обходного пути.

Итак, мои вопросы:

  1. Кто-нибудь был в состоянии макросизировать новое полностью, не манипулируя огромным количеством кода? (Относительно безболезненно)
  2. Есть ли другой способ перестроить мой заголовок STL, включая директивы?

Спасибо

1 Ответ

3 голосов
/ 14 февраля 2011

Вы можете поймать новое место размещения с помощью вариационного макроса:


#define NEW_DEBUG(...) NEW_DEBUG2(_NORMAL_BLOCK, __FILE__, __LINE__, __VA_ARGS__ )
#define new NEW_DEBUG

Но препроцессор, похоже, не позволяет определять макрос как с аргументы и без, и макрос без аргументов применяется первым, поэтому я не нашел способа сделать это за один проход препроцессора. Но это кажется возможным с двумя, если бы мы выполнили первый проход с вышеуказанными макросами и / E, затем второй проход с


#define NEW_DEBUG new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define NEW_DEBUG2(...) new(__VA_ARGS__ )
...