web-dev-qa-db-ja.com

C ++、関数の名前を取得します

C++では、このようなポインターから関数のシグネチャ/名前を取得する方法はありますか?

void test(float data) {}
cout << typeid(&test).name();

このデータをロギングに使用したいと思います。

16
Max Frai

現在の関数名をログに記録するだけの場合、ほとんどのコンパイラには__FUNCTION__マクロがあり、コンパイル時に現在の関数名が提供されます。

また、実行時に現在の呼び出しスタックと関数名に関する詳細情報を提供できるスタックウォーキングテクニック(ここでは Windowsの例 )を探すこともできます。

18
Jack Shainsky

C++、ポインターを介して呼び出し元の関数の名前を取得します。

オプション1:独自の関数名レコーダーをロールします

「関数へのポインタ」を「関数名」に解決する場合は、使用可能なすべての関数の独自のルックアップテーブルを作成し、ポインタアドレスをルックアップテーブルのキーと比較して、名前を返す必要があります。 。

ここで説明する実装: https://stackoverflow.com/a/8752173/445131

オプション2:__func__を使用

GCCは、現在の関数の名前を文字列として保持するこの魔法の変数を提供します。これはC99標準の一部です。

#include <iostream>
using namespace std;
void foobar_function(){
    cout << "the name of this function is: " << __func__ << endl;
}
int main(int argc, char** argv) {
    cout << "the name of this function is: " << __func__ << endl;
    foobar_function();
    return 0;
}

出力:

the name of this function is: main
the name of this function is: foobar_function

注:

__FUNCTION____func__の別名です。古いバージョンのGCCは、この名前のみを認識します。ただし、標準化されていません。最大の移植性が必要な場合は、__func__を使用することをお勧めしますが、プリプロセッサでフォールバック定義を提供して、未定義の場合は定義します。

 #if __STDC_VERSION__ < 199901L
 # if __GNUC__ >= 2
 #  define __func__ __FUNCTION__
 # else
 #  define __func__ "<unknown>"
 # endif
 #endif

ソース: http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html

23
Eric Leschinski

関数の名前を取得する方法はありません。実行可能ファイル内に存在しないという理由だけで。コードがコンパイルされてリンクされると、完全に消えます。

関数/変数の名前を変更してみてください。実行可能ファイルは同じになります(ビルドの日付/時刻、デバッグ情報IDなど、コンパイラが配置する可能性のある変更可能なものを除く)。

また、実行可能ファイルをエディターで開いて、関数名を探してみてください。ほとんどの場合、それは見つかりません。

ただし、実行時に関数名を見つけるのに役立つプログラムによる「装飾」を配置することもできます。

2
valdo

C++で関数の名前を取得することはできませんが、ポインターを出力して、後で関数名のバイナリー(削除されていない場合)を確認することはできます。署名は、タイプ名が実際には「人間が読める形式」ではないという点で、実行しているとおりに正確に印刷できます。コードの出力の意味については、コンパイラのドキュメントを確認してください。 g ++では、出力はPFvfEになりますが、これは完全には理解できませんが、void(P)を返し、float(F)を単一の引数として取る関数(v)へのポインター(f)を識別します。 Eが何であるか私に聞かないでください...

(今はドキュメントをチェックする時間がありません。サンプルプログラムで遊んで、次のことを推測しました:さまざまな関数シグネチャを出力します)

100%確信はありませんが、これはリフレクション(Java)のように思えます。また、C++はこのようなものをサポートしていません。わからないかもしれませんが、C++ではまだ見たことがありません。

0
InsertNickHere