首页 > 解决方案 > 为什么宏不能使用静态函数?

问题描述

我正在查看这个 github记录器项目,并在我自己的环境中尝试它。我试图将函数更改为log_logstatic以便不能在不同的文件中调用它,并且会强制“用户”(我)只使用宏。

当我将函数更改为静态时,我在 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, ...);

标签: cstatic

解决方案


您会收到“未定义的引用”链接器错误,因为该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,向您的团队中任何倾向于滥用它的成员提供适当的警告。


推荐阅读