我正在编写一个只有头的记录器库,我需要全局变量来存储当前的记录器设置(输出标志、日志文件描述符等(。我的想法:
- 我不能将变量声明为extern,因为我没有访问翻译单元来定义它们
- 我不能只在标题中定义全局变量,因为这会导致多个定义
- 头函数中的静态变量乍一看可能不错,但事实是,每个翻译单元都有自己的"全局"变量副本,这很尴尬,而且肯定是错误的
- 我也不认为在我的情况下可以避免全局变量(尽管这是我想做的(,因为我显然必须在日志函数调用之间以某种方式存储设置
有没有我还没有考虑过的变体?是否有其他方法可以使全局变量仅使用标头。
p.s.我正在寻找c99/c++11兼容的解决方案,并可能使用gcc破解(gcc>=4.8(
一种方法是将选项隐藏在返回对本地静态选项的引用的函数后面。只要不违反ODR(例如,函数的某些宏相关更改(,就可以保证本地静态变量在整个程序中是唯一的。举个简单的例子,这可以在头文件中:
inline bool& someOption()
{
static bool opt = false;
return opt;
}
在翻译单元中:
someOption() = true;
将选项分组到一个结构中并将上述技术应用于该结构的实例可能会很有用。
请注意,这种方法仅限于C++(感谢@rici提供的提示(,并且可能只是在使用gcc的C中意外实现的。
如下构建库:
MyLibrary.h:
extern int foo;
extern int bar;
...
#ifdef MY_LIBRARY_IMPL
int foo;
int bar;
...
#endif
然后,在库文档中,指定在一个翻译单元中,库的用户应在包含头文件之前#define MY_LIBRARY_IMPL
。