Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

replacing new with macro conflicts with placement new

I've got a massive application (several million LOC, and tens of thousands of files), and I'm trying to use the debug crt to detect memory leaks. I'm trying to macro-ize new like so:

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

Now, my app is so big, so for me, ideally, I would put that in a header file and specifically include that in tens of thousands of CPP files. Not a fun task. So I've attempted to place this in a common header file in our SDK, which will get included in every translational unit.

The problem I'm running into is it seems to clash with some STL header files, and the compiler emits errors when placement new is used. I can change that in my own code, by using pragma's and disabling the new macro. Not a problem there. It's the STL header files that use placement new, I can't change.

I've figured out a work-around, by rearranging include directives in cpp files. For example:

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

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

But this is a difficult work-around because again, I have to go modify thousands of files, and make sure their STL headers are included before anything else. The ironic thing, is I created a hello world application to specifically test this problem: And the hello-world app of mine compiled fine. But my massive app doesn't, without this work-around.

So my questions are:

  1. Has anyone been able to macro-ize new completely without jiggling massive amounts of code? (In a relatively painless way)
  2. Any other way to get around re-arranging my STL header include directives?

Thanks

like image 569
C Johnson Avatar asked Feb 14 '11 10:02

C Johnson


1 Answers

You can catch placement new with a variadic macro:


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

But the preprocessor doesn't seem to allow defining a macro both with arguments and without, and a macro without arguments is applied first, so I didn't find a way to do this with a single preprocessor pass. But it seems possible with two, if we'd run first pass with above macros and /E, then second pass with


#define NEW_DEBUG new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define NEW_DEBUG2(...) new(__VA_ARGS__ )
like image 73
Shelwien Avatar answered Sep 21 '22 10:09

Shelwien