___func__
_、___FUNCTION__
_、および___PRETTY_FUNCTION__
_はプリプロセッサマクロとして扱われず、16.8定義済みマクロ名標準のセクション( N4527草案 )。
つまり、これらは フェーズ6 の文字列連結トリックでは使用できません。
_// Valid
constexpr char timestamp[]{__FILE__ " has been compiled: " __DATE__ " " __TIME__};
// Not valid!!!
template <typename T>
void die() { throw std::runtime_error{"Error detected in " __PRETTY_FUNCTION__}; }
_
私の知る限り、___FILE__
_、___DATE__
_、および___TIME__
_は、標準で述べられているように文字列リテラルに変換されます。
16.8定義済みマクロ名[cpp.predefined]
_
__DATE__
_ソースファイルの翻訳日:a _
"Mmm dd yyyy"
_形式の文字列リテラル。月の名前は、asctime関数によって生成された名前と同じで、最初の文字of ddは、値が10未満の場合はスペース文字です。翻訳の日付が利用できない場合は、実装定義の有効な日付が提供されます。_
__FILE__
_現在のソースファイルの推定名(文字列リテラル)。
_
__TIME__
_ソースファイルの変換時間:a-time関数によって生成された時間と同様に、フォーム__
"hh:mm:ss"
_の文字列リテラル。
___func__
_は、次の形式の関数ローカルの事前定義変数として標準で言及されています。
_static const char __func__[] = "function-name ";
_
つまり、これはローカル変数であるため、文字列連結のトリックは機能しません。
___FUNCTION__
_と___PRETTY_FUNCTION__
_については標準では言及されていませんが(実装は定義されていますか?)、___func__
_のように動作すると考えるのはかなり安全です。
したがって、問題は次のとおりです。なぜ___func__
_、___FUNCTION__
_および___PRETTY_FUNCTION__
_は関数ローカルの静的定数文字配列であるのに対し、___FILE__
_、___DATE__
_および___TIME__
_は文字列リテラルですか?この決定の背後にある理論的根拠(ある場合)は何ですか?
拡大する __func__
前処理時に、プリプロセッサはどの関数を処理しているかを知る必要があります。解析はプリプロセッサがすでに行われた後で行われるため、プリプロセッサは通常それを知りません。
一部の実装は前処理と解析を組み合わせており、それらの実装では__func__
思い通りに機能します。実際、私が正しく思い出せば、MSVCの__FUNCTION__
はそのように機能します。しかし、翻訳のフェーズを分離する実装に対する不合理な要求です。