Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of `static char THIS_FILE[] = __FILE__;`?

What is the point of static char THIS_FILE[] = __FILE__;?

Intro: What does it do? Where does it come from?

MFC, Microsofts native class library for Windows, has a DEBUG_NEW macro that tracks memory allocations and the place they happened (in the user code).

For this to work, the VS wizard puts the following code block into every cpp file: (not in header files)

#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
#endif

and the debug new macro is defined as (in afx.h):

#define DEBUG_NEW new(THIS_FILE, __LINE__)

The whole machinery will result in meaningful leak detection output like:

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {615} normal block at 0x04081CE0, 56 bytes long.
 Data: <¬9Í]            > AC 39 CD 5D 13 00 00 00 13 00 00 00 01 00 00 00 
c:\my\dev\path\myfile.cpp(237) : {614} normal block at 0x04087FC0, 4 bytes long.
 Data: <ð   > F0 1C 08 04 
Object dump complete.

So, what's the question again?

What leaves me puzzled is what the THIS_FILE char array is for. The machinery doesn't make sense. If they'd defined DEBUG_NEWjust as:

#define DEBUG_NEW new(__FILE__, __LINE__)

They could just place it in a header and be done with it instead of having that ifdef block in every file.

So, what's the point of THIS_FILE?

(Incidentally, this is exactly what MS' CRT does with malloc and _malloc_dbg where the debug macro is defined in the header crtdbg.h as:

#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

)

So again, why is it done the complicated way in the MFC DEBUG_NEWmacro when the simple way would work (better)???


Update: Ha! I recently noticed that the VS2005 wizard does not put the definition of THIS_FILE into a generated cpp file.

Investigating it, it seems that MS decided some time ago, that it is not neccessary anymore, as in afxtempl.h the following is defined:

#undef THIS_FILE
#define THIS_FILE __FILE__

Still, I guess the question keeps being the same, as to why it was ever neccessary. (And I guess the answer with the memory requirement way back then is pretty valid.)


like image 397
Martin Ba Avatar asked Nov 07 '12 18:11

Martin Ba


1 Answers

The debug allocator stores a pointer to the file name in the heap block. Just 4 bytes instead of having every allocated block also having to allocate room for the file name.

Note that this can cause loss of debug info when the leaked block was allocated by a DLL and that DLL was unloaded by the time the leak report is generated.

Only the character array THIS_FILE is guaranteed to be always the same in the translaton unit. Not __FILE__, that's a literal. And two literals are not guaranteed to have the same address, even if they have the same value, meaning that a compiler could create a distinct literal -- and use up memory -- for each use of __FILE__.

like image 55
Hans Passant Avatar answered Oct 02 '22 22:10

Hans Passant