【发布时间】:2016-09-12 12:55:00
【问题描述】:
我正在维护一个自定义日志系统,该系统使用宏来执行诸如将时间戳和源文件名附加到每条消息的操作。所以像:
AI_LOG("Hello %s", "World!");
可能会导致:
(16.38) HelloWorld.cpp LOG: Hello World!
目前,它在堆栈上创建一个 char* 缓冲区,将输出的初始部分放在缓冲区的开头,然后使用 snprintf 将输出复制到缓冲区的其余部分。这一切都有效......除了它在堆栈上创建缓冲区,如果我有足够深的堆栈和足够的日志语句,并且我没有保持缓冲区非常小(例如 256 个字符),我可以得到堆栈溢出。我现在需要输出更长的字符串,因此将所有这些缓冲区放在堆栈上不再适合我了。
考虑到这一背景...我想移动到一个全局 char 数组,我将把它做得很大(开始可能是 4K 字符)。但是,我的理解是,如果我只是说这样的话:
#define AI_OUTPUT_BUFFER_SIZE 4092
char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE];
在我的输出系统的 .h 文件中,我冒着被包含该 .h 文件的每个文件创建一个单独的缓冲区的风险。这是一个真正的问题吗?如果是这样,是否有一种好的(编译器不可知、符合 C++98、不使用 Boost)方法来获得我想要的单个缓冲区?
我倾向于在标题中这样做:
#define AI_OUTPUT_BUFFER_SIZE 4096
class AIOutputBuffer
{
public:
static char buffer[AI_OUTPUT_BUFFER_SIZE];
};
然后在 .cpp 中我可以:
char GAIA::AIOutputBuffer::buffer[AI_OUTPUT_BUFFER_SIZE];
但这让我对链接器感到头疼……也许我还没有做对吗?
在人们提出建议之前...是的,我可能会重写它以使用字符串或流...但我真的不想重写整个系统,我也没有时间和资源来这样做.这个系统运行良好,给了我很大的灵活性——我只需要处理内存使用问题。
【问题讨论】:
-
你为什么不使用某种没有缓冲区的调用 cout 或类似的宏?
-
为什么要使用宏?如果编译器不会内联您的日志记录函数,那么将代码内联是一个坏主意。
-
@user4581301 如果您使用函数,您将无法访问行或文件信息。
-
在标题中使用
extern声明并在您的源文件之一中定义它。 -
@WilliamKappler: "如果您使用函数,您将无法访问行或文件信息。" 您可以创建一个函数,将行和文件宏作为论据。
标签: c++ c arrays global-variables c++98