C ++プリプロセッサマクロのロギングエラー__LINE __、__ FUNCTION__
-
05-07-2019 - |
質問
単純なエラーロギングを既存のアプリに組み込みようとしていますが、現時点ではcout
を使用してエラーを報告するため、<<
演算子を使用して同様のインターフェイスを維持したいと考えていました。ただし、エラーが発生した行と機能をログに記録する必要がありますが、ログを記録する必要があるたびに__LINE__, __FUNCTION__
を入力する必要はありません。誰かが私が__LINE__
マクロを別の関数内で使用できるようにするためのトリックを知っていますか?それが理にかなっていることを願っています。
class myLogClass {
uint8_t level;
public:
bool operator<<( const char * input );
};
bool myLogClass::operator<<( const char * input ) {
logItInSQL( input );
return true;
}
毎回これの代わりに
myLogClass << "Line No: " << __LINE__
<< " Function: " << __FUNCTION__
<< " Error: " << "This is my error to be logged";
できることだけをしたい:
myLogClass << "This is my error to be logged";
bool myLogClass::operator<<( const char * input ) {
logItInSQL( " Line No: __LINE__" );
logItInSQL( " Function: __FUNCTION__" );
logItInSQL( " Error: " + input );
return true;
}
解決
myLogClass << "Line No: " << __LINE__ ...
operator <<
を返すため、bool
チェーンは機能しません。
bool myLogClass::operator << (const char * input)
次のようにストリーム挿入を定義するのが慣例です:
std::ostream& myLogClass::operator << (std::ostream& o, const char * input) {
// do something
return o;
}
これを実行:
#define log(o, s) o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s // note I leave ; out
さらに、マクロをdo-while
ループでラップできます:
#define log(o, s) do { o << "Line No: " << __LINE__ << \
" Function: " << __FUNCTION__ << \
" Error: " << s; \
} while(0) // here, I leave ; out
その後、楽しく書くことができます:
myLogClass myLogger; // do this
// use it
log(myLogger, "This is my error to be logged"); // note the ;
他のヒント
ANSI C(これはC ++でも動作するはずです)では、可変個の関数とプリプロセッサマクロを使用して実行できます。以下の例を参照してください。
#include <stdio.h>
#include <stdarg.h>
#define MAXMSIZE 256
#define MyDebug(...) MyInternalDebug(__FILE__,__FUNCTION__,__LINE__,__VA_ARGS__)
void MyInternalDebug( char *file, char *function, const int line, const char *format, ... )
{
char message[MAXMSIZE];
// Variable argument list (VA)
va_list ap;
// Initialize VA
// args : Name of the last named parameter in the function definition.
// The arguments extracted by subsequent calls to va_arg are those after 'args'.
va_start(ap, format);
// Composes a string with the same text that would be printed if 'format' was used on printf,
// but using the elements in the variable argument list identified by 'ap' instead of
// additional function arguments and storing the resulting content as a C string in the buffer pointed by 'message'.
// * The state of arg is likely to be altered by the call.
vsprintf(message, format, ap);
// Custom print function
printf("%s\t%s\t%d\t%s\n",file, function, line, message);
// Finzalize use of VA
va_end(ap);
}
int main ()
{
MyInternalDebug(__FILE__, __FUNCTION__, __LINE__, "An error occured with message = '%s'", "Stack Overflow");
MyDebug("Another error occured with code = %d", 666);
return 0;
}
いいえ、これがマクロでロギングが行われる理由です。 __LINE__
共通のロギング関数ではなく、問題の行でプリプロセッサによって展開する必要があります。
アダム・ミッツが述べたように、電話の代わりに__LINE__を使用する必要があります。
<!> quot; additionalInfo <!> quot;のような追加のパラメーターを追加することをお勧めします。そして、この<!> quot; additionalInfo <!> quotを生成するマクロを作成します。 __LINE__および__FUNCTION__を使用します。
コンパイルする最初の回答でコードを取得できませんでした。私はタスクをうまく達成するこの単純なマクロを使用します:
#define qlog(s) std::cerr << __FUNCTION__ << "::" << __LINE__ << "\t" << s << endl