我有一个使用宏来跟踪消息的日志库.此宏使用类似的预定义宏,__func__并__PRETTY_FUNCTION__指示消息记录在哪个函数/方法中.
我的日志库的宏在我的日志库的主标题中定义,在任何函数之外.
出于某种原因,预处理的代码包含__func__(或者__PRETTY_FUNCTION__如果我使用此代码)litterally,就像这些预定义的宏不存在一样.但我知道它们确实存在,因为如果我使用它们而不使用我的lib的跟踪宏,它们就可以了!
这是我的libs宏:
#if _MSC_VER >= 1400 // If >= VS2005
#define _TRACE_FUNC_SIGNATURE __FUNCSIG__
#elif defined(__ANDROID__) || defined( __GNUC__ ) && defined( __cplusplus ) // If G++ and/or Android NDK
#define _TRACE_FUNC_SIGNATURE __func__
#else
#error // Unsupported compiler
#endif
// Forces the reprocessing of x to properly expand __VA_ARGS__ when using MSVC compiler
#define _TRACE_REPROCESS( x ) x
#define _TRACE_X( _methodName_, _logCatPtr_, ... ) \
do { \
::dbg::LogCategory * const _catPtrVal_ = (::dbg::LogCategory *)(_logCatPtr_); \
if( NULL != _catPtrVal_ && _catPtrVal_->IsEnabled() ) \
{ \
_TRACE_REPROCESS( _catPtrVal_->_methodName_( _TRACE_FUNC_SIGNATURE " - " __VA_ARGS__ ); ) \
} \
} while( false )
#define TRACE_E( _logCatPtr_, ... ) _TRACE_X( Error, _logCatPtr_, __VA_ARGS__ )
#define TRACE_W( _logCatPtr_, ... ) _TRACE_X( Warning, _logCatPtr_, __VA_ARGS__ )
#define TRACE_I( _logCatPtr_, ... ) _TRACE_X( Info, _logCatPtr_, __VA_ARGS__ )
Run Code Online (Sandbox Code Playgroud)
我知道这些宏没有理由在函数外定义,但由于我只在函数/方法中使用我的跟踪宏,所以应该在那里定义它们!
我正在使用eclipse提供的默认Android NDK编译器,我读到的是某种扩展G ++.
编辑:如果我替换__func__实际的字符串litteral,它的工作原理,没有语法错误.这让我觉得__func__在我的宏中使用时肯定没有定义.
在一些实现中,__func__是变量,而不是宏(至少在gcc中).所以,你不能使用它,就好像它是一个字符串文字.
所以这 :
_TRACE_REPROCESS( _catPtrVal_->_methodName_( _TRACE_FUNC_SIGNATURE " - " __VA_ARGS__ ); )
Run Code Online (Sandbox Code Playgroud)
必须以不同的方式书写.我不知道如何_catPtrVal_->_methodName_实现,但如果它可以采取多个参数,那么像这样的东西可能会做到这一点:
_TRACE_REPROCESS( _catPtrVal_->_methodName_( _TRACE_FUNC_SIGNATURE, " - " __VA_ARGS__ ); )
Run Code Online (Sandbox Code Playgroud)
如果没有,那么你将不得不使用一些其他方式__func__与日志行的其余部分连接(使用std::stringstream例如.).
C标准指定__func__如下:
标识符
__func__应由翻译者隐式声明,就像紧跟每个函数定义的左括号一样,声明
static const char __func__[] = "function-name";出现了,其中function-name是词法封闭函数的名称.
IE浏览器.它将实现是否作为变量或宏提供给它(只要它的行为就好像它的定义如上所示).