我通常使用#define
宏来添加代码,这些代码在作为调试时间而不是作为发行版时将在此处。例如:
#ifdef NDEBUG
# define LOG(msg) (void)msg
#else
# define LOG(msg) MyDebugLogger(msg)
#endif
相反,我在考虑使用简单的函数,只是不提供发布方法的主体:
void MyDebugLogger(std::string const& msg);
在MyDebugLogger.cpp中:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "\n"; // Or whatever
#else
(void)msg;
#endif
}
我希望编译器能够清除调用并在Release中增加否额外费用。我对么? 出于某种原因,这会是一个不好的做法吗?
编辑:我的问题是:如果我像以前一样使用宏,我知道在发布模式下,可执行文件将变得更小,更快,因为所有代码都已删除。 如果使用该功能,会一样吗?正如编译器可能会理解的那样,该函数不执行任何操作,因此没有必要。 (或者它将增加一个额外的,甚至很小的调用空函数)
答案 0 :(得分:1)
实际上,您将执行与宏相同的操作:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "\n"; // Or whatever
#endif
}
答案 1 :(得分:1)
您的示例应该进行一些调整。在当前版本中,编译器仅“看到”函数签名,并发出对其符号的调用,该符号稍后将通过链接器进行解析,因此它无法自行对其进行优化。 (链接时间优化可能会对此有所帮助,但这在很大程度上取决于您的设置,而动态链接将使此操作变得不可能)。所以也许尝试这样的事情 在标题中:
// Assuming you are using clang or gcc,
// but is required to not give an error by the standard and probably
// not even needed.
[[gnu::always_inline]]
void MyDebugLogger(std::string const& msg [[maybe_unused]])
{
#ifdef NDEBUG
MyDebugLoggerImplementation(msg);
#endif
}
然后在.cpp文件中实现它。这种方法的另一个好处是您 方法需要使用NDEBUG编译Logger,而此方法提供了客户端代码的选择。