我有一个提供日志工具的全局宏#define LOG_LOG(name,level,msg,...) {
我通过另一个宏LENTER
使用日志工具来间接调用/依赖LOG_LOG
(下面的定义)。宏看起来像这样(在logger.h
中定义):
#define LOG_LOG(name,level,msg,...) { \
#if defined(OS_MACOSX)\
int tid=mach_thread_self();\
#elif defined(OS_LINUX)\
int tid=syscall(__NR_gettid);\
#elif defined(OS_FREEBSD)\
int tid=reinterpret_cast<int64>(pthread_self());\
#endif\
if (level<=LOGLEVEL_WARNING){\
fprintf(stderr,"%s %i %s:%s():%i",name, tid, __FILE__,__FUNCTION__,__LINE__);\
fprintf(stderr," " LOG_ADDITIONAL);\
fprintf(stderr,"--> " msg, ##__VA_ARGS__);\
fprintf(stderr,"\n");\
}else{\
printf("%s %i %s:%s():%i",name, tid, __FILE__,__FUNCTION__,__LINE__);\
printf(" " LOG_ADDITIONAL);\
printf("--> " msg, ##__VA_ARGS__);\
printf("\n");\
}\
}
#if LOGLEVEL>=LOGLEVEL_TRACE
#define LTRACE(msg,...) LOG_LOG("Trace",5,msg,##__VA_ARGS__)
#else
#define LTRACE(msg, ...) {}
#endif
#define LENTER LTRACE("entering method")
这些宏的客户端代码如下所示:
template<typename T>
inline void tvector<T>::random() {
LENTER;
for (int i = 0; i < size(); ++i) {
elem(i) = (double) rand() / (double) RAND_MAX;
}
}
但我仍然得到错误:
/Users/bravegag/code/fastcode_project/code/src/vector.h: In member function 'void tvector<T>::random()':
/Users/bravegag/code/fastcode_project/code/src/vector.h:223:2: error: there are no arguments to 'LOG_LOG' that depend on a template parameter, so a declaration of 'LOG_LOG' must be available [-fpermissive]
我没有得到,因为这是一个可用且全局定义良好的宏,并且与客户端成员函数tvector<T>::random()
的类的模板参数完全无关。关于这个问题的研究我找到了链接http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html,但这很令人困惑,远远不是我手边的问题。
此错误告诉我LOG_LOG
的定义不可用......但确实如此。我真的不知道这个“两阶段名称查找”如何提高代码的质量,而不是创建极其混淆的编译器错误。
/Users/bravegag/code/fastcode_project/build_debug$ g++ --version
g++ (MacPorts gcc46 4.6.3_2) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
/Users/bravegag/code/fastcode_project/build_debug$ uname -a
Darwin Macintosh-4.local 11.4.0 Darwin Kernel Version 11.4.0: Mon Apr 9 19:32:15 PDT 2012; root:xnu-1699.26.8~1/RELEASE_X86_64 x86_64
答案 0 :(得分:4)
#define LOG_LOG(name,level,msg,...) { \
#if defined(OS_MACOSX)\ <--------------- Heh?
int tid=mach_thread_self();\
#elif defined(OS_LINUX)\
int tid=syscall(__NR_gettid);\
#elif defined(OS_FREEBSD)\
int tid=reinterpret_cast<int64>(pthread_self());\
#endif\
您不能在#define
中使用其他预处理程序语句,因此您看到的其他错误可能是因为编译器甚至不理解您的LOG_LOG
定义。
答案 1 :(得分:1)
您应该将宏重写为以下内容:
#if defined(OS_MACOSX)
#define THREAD_ID mach_thread_self()
#elif defined(OS_LINUX)
#define THREAD_ID syscall(__NR_gettid)
#elif defined(OS_FREEBSD)
#define THREAD_ID reinterpret_cast<int64>(pthread_self())
#endif
#define LOG_LOG(name,level,msg,...) do { \
int64 tid = THREAD_ID; \
if (level<=LOGLEVEL_WARNING) { \
... \
} while(0)
请注意,如果至少在您的一个选项中,线程ID将是64位整数,则应始终使用64位整数(否则您将无法显示BSD的正确值。请记住将相应的类型传递给printf
或者使线程号记录平台依赖。另外,据我所知,所有三个平台都支持POSIX,所以你可能想要提供一个更容易维护的统一实现。