0

ロギング機能を提供するグローバル マクロがあります。間接的に呼び出す/依存する#define LOG_LOG(name,level,msg,...) {別のマクロを介してロギング機能を使用します(以下の定義)。マクロは次のようになります ( で定義)。LENTERLOG_LOGlogger.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]

これは取得できません。これは、グローバルに利用可能で適切に定義されたマクロであり、クライアント メンバー function のクラスのテンプレート パラメーターとはまったく関係がないためですtvector<T>::random()。この問題について調査したところ、http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.htmlというリンクが見つかりましたが、これは紛らわしく、手元にある問題とはかけ離れています。

このエラーは、の定義がLOG_LOG利用できないことを示しています...しかし、利用可能です。この「2段階の名前検索」が、非常に難読化されたコンパイラエラーを作成する以外に、コードの品質をどのように改善するかは本当にわかりません。

/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
4

2 に答える 2

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

于 2012-06-30T11:32:04.373 に答える
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)

オプションの少なくとも1つでスレッドIDが64ビット整数になる場合は、64ビット整数を使用する必要があることに注意してください(そうでない場合、BSDの正しい値は表示されません。適切なタイプを渡す printfか、スレッド番号ロギングプラットフォームに依存します。また、私が知る限り、3つのプラットフォームすべてがPOSIXをサポートしているため、保守が容易な統一された実装を提供することをお勧めします。

于 2012-06-30T13:36:52.967 に答える