__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对象无可奈何。此时，最安全的办法是使用异常处理，具体参见上述教程，因为异常是可以在处理后，再次向上层函数传播的。

















