12

有什么意义static char THIS_FILE[] = __FILE__;

简介:它有什么作用?它从何而来?

MFC 是微软的 Windows 原生类库,有一个DEBUG_NEW宏可以跟踪内存分配和它们发生的位置(在用户代码中)。

为此,VS 向导将以下代码块放入每个 cpp 文件中:(不在头文件中)

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

并且调试新宏定义为(in afx.h):

#define DEBUG_NEW new(THIS_FILE, __LINE__)

整个机器将产生有意义的泄漏检测输出,例如:

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.

那么,又是什么问题呢?

让我感到困惑的是THIS_FILEchar 数组的用途。机器没有意义。如果他们定义DEBUG_NEW为:

#define DEBUG_NEW new(__FILE__, __LINE__)

他们可以将它放在标题中并完成它,而不是ifdef在每个文件中都有那个块。

那么,有什么意义THIS_FILE呢?

(顺便说一句,这正是 MS 的 CRT 所做的,malloc并且_malloc_dbg调试宏在标头中定义crtdbg.h为:

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

)

再说一遍,为什么在 MFC 宏中以复杂的方式完成,DEBUG_NEW而简单的方式可以工作(更好)???


更新:哈!我最近注意到 VS2005 向导没有将定义THIS_FILE放入生成的 cpp 文件中。

调查一下,似乎 MS 前段时间决定不再需要它了,afxtempl.h如下定义:

#undef THIS_FILE
#define THIS_FILE __FILE__

尽管如此,我想问题仍然是一样的,为什么它是必要的。(而且我想当时内存要求的答案是非常有效的。)


4

3 回答 3

9

调试分配器在堆块中存储指向文件名的指针。只需 4 个字节,而不是让每个分配的块也必须为文件名分配空间。

请注意,当泄漏的块由 DLL 分配并且在生成泄漏报告时已卸载 DLL 时,这可能会导致调试信息丢失。

只有字符数组THIS_FILE保证在翻译单元中始终相同。不是__FILE__,那是字面意思。并且不保证两个文字具有相同的地址,即使它们具有相同的值,这意味着编译器可以为每次使用__FILE__.

于 2012-11-07T20:07:00.670 回答
0

我相信,我可能是错的,这是在编译的 exe 中描述内存块。如果您要获得异常,这将有所帮助,您可以追溯内存地址链以找到有问题的代码,前提是您知道 dll/exe 加载的地址。

于 2012-11-07T19:51:21.363 回答
0

__FILE__在整个文件中是相同的,而__LINE__在每一行都有变化。因此,如果您在一个文件中有大量调试代码,则不能很好地合并常量的旧编译器会有很多不必要的字符串“filename.ext”副本。您也许可以使用 -fno-merge-constants 之类的东西来检查差异(对不起,这就是它的 gcc CFLAG,不确定 VS)。大多数编译器现在默认合并常量,不需要该定义。

于 2012-11-29T08:59:55.347 回答