c - 为什么宏不能使用静态函数?
问题描述
我正在查看这个 github记录器项目,并在我自己的环境中尝试它。我试图将函数更改为log_log
,static
以便不能在不同的文件中调用它,并且会强制“用户”(我)只使用宏。
当我将函数更改为静态时,我在 main 中得到未定义的引用,即使宏应该能够看到它。为什么是这样?有没有办法做到这一点?
#include <stdio.h>
#include <stdarg.h>
#define LOG_VERSION "0.1.0"
typedef void (*log_LockFn)(void *udata, int lock);
enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) log_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_warn(...) log_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
void log_set_udata(void *udata);
void log_set_lock(log_LockFn fn);
void log_set_fp(FILE *fp);
void log_set_level(int level);
void log_set_quiet(int enable);
void log_log(int level, const char *file, int line, const char *fmt, ...);
解决方案
您会收到“未定义的引用”链接器错误,因为该log_log
函数未在标头中定义;它只是被宣布。(请参阅了解定义和声明变量之间的区别;声明和定义函数的概念相似。)
通过说函数是static
,你是说log_log()
它将在定义你的函数的源文件中main()
定义,并且它也将在任何其他试图调用它的文件中单独定义(这将是浪费除非函数是琐碎的)。但是定义不存在——因此在链接程序时会收到“未定义的引用”消息。使用我的默认编译器选项,编译器(而不是链接器)也会告诉我声明为函数的static
函数未定义。
如果不经过诸如包含源文件(不是标头而是源文件)的扭曲,您将无法执行您尝试的操作,该文件log_log
在包含您的main()
函数的代码中定义。但是,您真的不想这样做;你真的,真的,真的不想这样做。
log_log(CS_POTATOES, "codswallop", -366, "abuse is rampant")
让懒惰保护你:打字比打字难log_trace("abuse is rampant")
,所以人们不太可能这样做。而且您始终可以搜索和替换对 的直接调用log_log
,向您的团队中任何倾向于滥用它的成员提供适当的警告。