预定义宏
C 编译器预定义了一组宏,提供编译时间、文件、行号、函数名等信息。这些宏在调试、日志、版本控制中非常有用。C99 引入了 __func__,C11 引入了 _Static_assert。
标准预定义宏
| 宏 | 含义 |
|---|---|
__FILE__ | 当前源文件名 |
__LINE__ | 当前行号 |
__DATE__ | 编译日期("Mmm dd yyyy") |
__TIME__ | 编译时间("hh:mm:ss") |
__func__ | 当前函数名(C99) |
__STDC__ | 标准 C 编译器定义为 1 |
__STDC_VERSION__ | C 标准版本(C99: 199901L) |
使用示例
#include <stdio.h>
#define LOG(msg) printf("[%s:%d %s] %s\n", \
__FILE__, __LINE__, __func__, msg)
void process(void)
{
LOG("Entering function");
/* 处理 */
LOG("Exiting function");
}
/* 输出:
[test.c:10 process] Entering function
[test.c:13 process] Exiting function
*/
编译时间信息
printf("Compiled on %s at %s\n", __DATE__, __TIME__);
/* Compiled on Jan 15 2024 at 14:30:00 */
func
void example(void)
{
printf("Function: %s\n", __func__); /* Function: example */
}
__func__ 是隐式声明的局部变量:static const char __func__[] = "function_name";
版本检查
#if __STDC_VERSION__ >= 199901L
/* C99 或更高 */
#include <stdint.h>
#else
#error "C99 required"
#endif
常见错误
假设 func 是宏:
#define LOG() printf("%s\n", __func__)
/* __func__ 不是宏,是隐式变量 */
/* 在宏中展开为定义宏的函数名,不是调用处 */
最佳实践
- 用
__FILE__和__LINE__定位错误 - 日志系统包含函数名信息
- 版本检查确保编译器兼容性
- 编译时间信息用于版本追踪
- 不要依赖编译器特定扩展宏