我有一个非常基础的类,将其命名为Basic,几乎用于更大项目中的所有其他文件。在某些情况下,需要调试输出,但在发布模式下,不应该启用它并且是NOOP。
目前标题中有一个定义,可根据设置打开或关闭makro。关闭时,这肯定是一个NOOP。我想知道,如果我有以下代码,如果编译器(MSVS / gcc)能够优化函数调用,那么它又是一个NOOP。 (通过这样做,交换机可以在.cpp中,切换速度会快得多,编译/链接时间也会快。)
--Header--
void printDebug(const Basic* p);
class Basic {
Basic() {
simpleSetupCode;
// this should be a NOOP in release,
// but constructor could be inlined
printDebug(this);
}
};
--Source--
// PRINT_DEBUG defined somewhere else or here
#if PRINT_DEBUG
void printDebug(const Basic* p) {
// Lengthy debug print
}
#else
void printDebug(const Basic* p) {}
#endif
答案 0 :(得分:2)
与所有这样的问题一样,答案是 - 如果它对你真的很重要,试试方法并检查发出的汇编语言。
答案 1 :(得分:1)
编译器可能会优化此代码,如果它在编译时知道printDebug函数的实现。如果printDebug位于另一个对象模块中,则可能只使用链接器使用整个程序优化来优化。但是测试它的唯一方法是读取编译器生成的汇编代码。 如果您已经有PRINT_DEBUG宏,则可以按照定义TRACE的方式对其进行扩展:
#define PRINT_DEBUG // optional #ifdef PRINT_DEBUG #define PRINT_DEBUG_CALL(p) printDebug(p) #else #define PRINT_DEBUG_CALL(p) #endif void printDebug(const Basic* p); class Basic { Basic() { simpleSetupCode; // this should be a NOOP in release, // but constructor could be inlined PRINT_DEBUG_CALL(this); } }; --Source-- // PRINT_DEBUG defined somewhere else or here #if PRINT_DEBUG void printDebug(const Basic* p) { // Lengthy debug print } #endif
答案 2 :(得分:1)
#if PRINT_DEBUG
#define printDebug _real_print_debug
#else
#define printDebug(...)
#endif
这样预处理器将在它到达编译器之前删除所有调试代码。
答案 3 :(得分:0)
错误,为什么不以不同的方式使用预处理器宏?
仅仅是我的头脑,如:
#define DEBUG_TRACE(p)
#ifdef PRINT_DEBUG
printDebug(p);
#else
;
#endif
答案 4 :(得分:0)
目前,大多数优化都是在编译时完成的。某些编译器LLVM能够在链接时进行优化。这是一个非常有趣的想法。我建议你看看。
等待这些优化,您可以做的是以下内容。定义一个宏,使您可以根据是否定义DEBUG来包含以下语句。
#ifdef DEBUG
#define IF_DEBUG (false) {} else
#else
#define IF_DEBUG
#endif
您可以像这样使用它
Basic() {
simpleSetupCode;
// this should be a NOOP in release,
// but constructor could be inlined
IF_DEBUG printDebug(this);
}
已经比
更具可读性 Basic() {
simpleSetupCode;
// this should be a NOOP in release,
// but constructor could be inlined
#if DEBUG
printDebug(this);
#endif
}
请注意,您可以将其用作关键字
IF_DEBUG {
printDebug(this);
printDebug(thas);
}