30

ログメッセージが呼び出された場所のファイル、行、および関数を記録するデバッグログメッセージ関数を構築しようとしています。

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __func__ , __FILE__, __LINE__ );

上記のコードは一部のコンパイラで動作しますが、すべてではありません。私のコードは、GCC および Microsoft Visual Studio と相互互換性がある必要があります。互換性を確保するために、以下の定義を追加しました。

#ifndef __FUNCTION_NAME__
    #if defined __func__ 
        // Undeclared 
        #define __FUNCTION_NAME__   __func__ 
    #elif defined __FUNCTION__ 
        // Undeclared
        #define __FUNCTION_NAME__   __FUNCTION__  
    #elif defined __PRETTY_FUNCTION__
        // Undeclared
        #define __FUNCTION_NAME__   __PRETTY_FUNCTION__
    #else
        // Declared
        #define __FUNCTION_NAME__   "N/A"   
    #endif // __func__ 

#endif // __FUNCTION_NAME__

#define DEBUG_PANIC(p) CLogging::Debuglogf( "Debug marker (%s) - ::%s() in file: %s(%d)", p, __FUNCTION_NAME__, __FILE__, __LINE__ );

上記のコード スニペットの問題は、#else マクロがすべてのコンパイラでアクティブであるのに対し、他のマクロはアクティブでないことです。言い換えると、 が事前定義されたマクロ#if defined __func__であるコンパイラでは false__func__です。

私の質問は

  • 関数名を見つけるためのクロス コンパイラ マクロを作成するにはどうすればよいですか?
  • a が使用できるかどうかはどうすればわかり__func__ますか?
4

4 に答える 4

16

多くの場合、 BoostBOOST_CURRENT_FUNCTIONは で定義されたクロスプラットフォーム ソリューション<boost/current_function.hpp>です。

于 2015-06-30T11:22:02.923 に答える
10

__FUNCTION__マクロは GCC と MSVC の両方に対して定義されていることを付け加えておきます。非標準ですが、両方のコンパイラで利用できます。

GCC 標準の定義済みマクロの引用:

C99 は を導入__func__し、GCC は__FUNCTION__長い間提供してきました。これらは両方とも、現在の関数の名前を含む文字列です (わずかな意味の違いがあります。GCC のマニュアルを参照してください)。どちらもマクロではありません。プリプロセッサは現在の関数の名前を知りません。__FILE__ただし、これらはおよび と組み合わせて使用​​ する傾向があり__LINE__ます。

MSVC 定義済みマクロの引用:

__FUNCTION__

関数内でのみ有効です。囲んでいる関数の装飾されていない名前を文字列リテラルとして定義します。

__FUNCTION__/EP または /P コンパイラ オプションを使用する場合、展開されません。

例については、を参照__FUNCDNAME__してください。

__FUNCTION__両方のコンパイラがそれを実装しているので、使用しても問題ありません。両方のコンパイラで同じ結果が得られない場合がありますが、状況によっては許容される場合があります。

于 2016-01-06T22:47:28.490 に答える