我正在开发一个类似于 GLib 日志记录的 API。
当标志
-DDEBUG
未传递给 GCC 时,我的 API 还可以禁用这些功能。
这意味着,二进制文件中没有残留物,如果未传递此标志,则所有这些调试函数(包括其参数)都不存在于可执行文件中。
它在 C 中完美运行,因为它是我可以轻松替换的宏函数;
std::cout
<< operator (such as
做同样的事情),但我无法管理<< operator like I manage parameters in C.这是我尝试过的;
调试.hpp
#include <iostream>
#define LOG_UNDEFINED (-1)
#define LOG_NONE 0
#define LOG_FATAL 1
#define LOG_ERROR 2
#define LOG_WARNING 3
#define LOG_INFO 4
#define LOG_DEBUG 5
#define LOG_TRACE 6
namespace debug
{
#ifdef DEBUG
class debug_cout
: public std::ostream
{
public:
debug_cout(std::streambuf *sbuf)
: std::ios(sbuf), std::ostream(sbuf)
{}
~debug_cout() {}
};
debug_cout cout(int l) {
static int level = l;
return debug_cout(std::cout.rdbuf());
}
#else
class debug_cout
: public std::ostream
{
public:
debug_cout() {}
~debug_cout() {}
};
debug_cout cout(int l) {
return debug_cout();
}
#endif
}
main.cpp
#include <debug/debug.hpp>
int main() {
debug::cout(LOG_ERROR) << "Hello " << 3 << std::endl;
return 0;
}
这样编译正确;
使用 -DDEBUG
标志,它输出 ;
Hello 3
如果没有-DDEBUG
,它不会输出任何内容,但是可执行文件中会有残留物。我看到使用
objdump
我的函数
debug::cout()
仍然存在并被调用。我也尝试过使用 GCC 优化标志
-O3
。
<< operator.
注意:如果我不能使用也不是问题namespace
注 2: 当我谈论残基时,我的意思是我的函数 debug::cout()
保留在 C++ 的可执行文件中并被执行(并且它什么也不做)。
#else
class debug_cout
: public std::ostream
你的NDEBUG
虚拟对象是一个ostream。这并不是什么!即使streambuf没有连接到任何东西,它也可能在运行时改变(因此必须检查)。您已经知道这一点,因为您在运行时在
DEBUG
分支中设置了相同的 Streambuf。你想要一个什么都不做的类型,所以就这样写:
#else
class debug_cout {};
并且您希望它使用流插入语法,所以写 that:
template <class T>
debug_cout& operator<<(debug_cout& s, T&&)
{
return s;
}