Files
build_infra/0_笔记/
T
2026-06-16 10:23:51 +08:00

47 lines
2.2 KiB
Plaintext

__func__:当前函数的名称。
__FILE__:当前源文件的路径。
__LINE__:当前源文件的行号。
__TIME__:编译时的时间。
__DATE__:编译时的日期。
__STDC__:如果符合 ANSI C 标准,定义为 1。
__cplusplus:当前 C++ 标准的版本。
__PRETTY_FUNCTION__:当前函数的完整名称。
__FUNCTION__:当前函数的名称(与 __func__ 类似)。
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__:当前 GCC 编译器的版本信息。
__VA_ARGS__:宏的变参。
参见《C++程序设计精要教程》,程序编译后执行过程是这样的:
1. 开工函数,它会初始化全局对象和函数外的static对象;
2. main函数;
3. 收工函数,自动析构开工时初始化的全局对象、以及函数内定义的局部static对象。
开工和收工函数的名称不重要,依赖于编译器。
exit后会去执行收工函数,而abort后不执行收工函数。return返回后,也会去执行收工函数。
abort函数不执行收工函数,意味全局对象和static对象不会被自动析构,这样可能会导致内存泄露。
return时会析构其函数内定义的局部非static对象;但是,exit和abort都不会自动析构局部非static对象,
这样也可能导致部分内存泄漏。因此,return最安全,exit次之,abort最差。
注意收工函数可以通过调用特定函数,替换成程序自己定义的收工函数,该特定函数的名称也取决于编译器。
在执行自己定义的收工函数的过程中,可通过替换时返回的函数指针回调以前的收工函数,
让其完成全局和static对象的自动析构。具体方法参见上述教材,这是一本注重实战开发的教材。
当然,在abort和exit前,主动析构本层函数局部非static对象,不失为一种防止内存泄漏的办法。但是,这种方法有其局限性,当函数调用嵌套的层次很深时,你只能主动析构本层函数定义的局部非static对象,对所有上层函数定义的局部非static对象无可奈何。此时,最安全的办法是使用异常处理,具体参见上述教程,因为异常是可以在处理后,再次向上层函数传播的。