2010-03-17 22 views
1

我有一个C记录仪++应用程序,使用了如下定义:是否可以创建一个不会产生警告的空函数?

#define FINEST(...) Logger::Log(FINEST, _FILE, __LINE, __func, __VA_ARGS_) 

不过我想这样做是为了能够,因为他们在我的系统性能产生严重影响关掉这些日志。而且,仅仅让我的记录器不能写入系统日志是不够的。我真的需要摆脱由日志产生的代码。

为了做到这一点,我改变了定义到:

#define FINEST(...) 

其中一期工程,但这会产生一大堆警告的在我的代码,因为现在的变量是未使用。所以我想要的是一种实际上不存在的NULL FUNCTION,但不会为未使用的变量产生警告。所以,换一种说法,我希望它在没有警告的情况下编译(即编译器认为变量用于函数),但函数实际上并不存在于应用程序中(即不产生性能影响) 。

这可能吗?

谢谢!

+0

这是更容易,如果你把你的'#defines'内反引号(代码)来读取。 – Cameron 2010-03-17 20:39:48

+0

人们会提供一些建议,这些建议会让编译器相信这些变量在不被使用时会被使用 - 这会损害您的发布代码中的优化。 – 2010-03-17 20:41:43

+0

为什么不只是调整编译器的警告级别?这似乎更容易。 – 2010-03-17 20:42:53

回答

3

您可以定义未命名的参数的空函数:

void nullFunc(int, int, int, const char*, ...) { 
} 

然后宏重新定义调用这个函数:

#define FINEST(...) nullFunc(FINEST, _FILE, __LINE, __func, __VA_ARGS_) 
+0

这不会在程序对象文件中创建代码,从而影响性能吗? – bbazso 2010-03-17 20:57:33

+0

如果您内联nullFunc,则不会创建代码。 – 2010-03-17 21:21:01

+0

@Robert,虽然会创建用于评估参数的代码。想象一下'FINEST(generateStackTrace())'会尝试在发布模式下创建一个strack-trace字符串。 – 2010-03-17 21:22:52

4

您是否考虑过关闭编译器的特定警告?
它可能不是一个好主意,但如果你需要一个快速和肮脏的解决方案...

+1

+1,因为它是一个好主意。在调试版本中启用警告(该警告未被错误触发并且很有用),然后禁用生产版本(因为我们已经从调试版本中获得了该警告的好处)。 – 2010-03-17 20:47:45

3
template<bool implemented> 
void Logger::Log(...); 

template<> 
void Logger::Log<true>(...) 
{ 
    // with implementation 
} 

template<> 
void Logger::Log<false>(...) 
{ 
    // without implementation 
} 

// USE: 
#define FINEST(...) Logger::Log<true>(FINEST, _FILE, __LINE, __func, __VA_ARGS_) 
// or 
#define FINEST(...) Logger::Log<false>(FINEST, _FILE, __LINE, __func, __VA_ARGS_) 

// EVEN BETTER (w/o macro): 
// flag to switch on/off logging 
const bool with_log = true; // or =false 

// use 
Logger::Log<with_log>(/* place arguments here */); 
+0

这不会在程序对象文件中创建代码,从而影响性能吗? – bbazso 2010-03-17 20:56:57

+1

这不会创建代码。至少在大多数具有优化的现代编译器上。 – 2010-03-17 20:58:14

3

在科莫和GCC,警告如果您缠绕变量消失成sizeof

#define FINEST(...) ((void)sizeof(__VA_ARGS__)) 

为了避免有关逗号运算符的左侧或右侧有没有影响(如果扩展为sizeof(a, b)为例),您可以引入有自己的逗号操作调试,抵消型的海湾合作委员会的警告:

struct debug_nullify { }; 

// doesn't need a definition 
template<typename T> 
debug_nullify operator,(debug_nullify, T const &); 

#define FINEST(...) ((void)sizeof(debug_nullify(), __VA_ARGS__)) 

sizeof的好处是不会评估参数表达式。

+1

你和那个逗号运算符。 – GManNickG 2010-03-17 21:36:14

+0

啊!我打算发布这个!哦,等等,我已经做到了:http://stackoverflow.com/questions/2230768/what-is-the-optimization-with-highest-roi-you-ever-did-to-your-code/2230868#2230868 Blargh。 – MSN 2010-03-17 21:37:26

+0

@GMan,哈哈,我忍不住发布了一个愚蠢的解决方法xD请参阅@DavidX的答案是否是真正的方法xD – 2010-03-17 21:40:19

2

我会建议在释放去除声明太:

int somefunc(int foo, int bar, void* baz) 
    { 
    DEBUGVAR(Logger,log); 
    int othervar; 
    /* stuff */ 
    MAYBELOG(log,"something happened: %i",othervar); 
    /* other stuff */ 
    return 0; 
    } 

定义:

#if DEBUGLEVEL>0 
#define DEBUGVAR(type,...) type __VA_ARGS__ 
#define MAYBELOG(logger,str,...) logstuff(logger,__FLIE__,__LINE__,str,__VA_ARG__) 
#else 
#define DEBUGVAR(type,...) 
#define MAYBELOG(logger,str,...) 
#endif 
+0

我最喜欢这个想法。如果我是他,我会亲自去解决这个问题。 – 2010-03-17 21:38:50

相关问题