5

ここで私の以前の質問に多少関連しています

d の関数またはメソッド内から呼び出しオブジェクトを取得する方法はありますか?

例:

class Foo
{
    public void bar()
    {
        auto ci = whoCalledMe();
        // ci should be something that points me to baz.qux, _if_ baz.qux made the call

    }
}

class Baz
{
    void qux()
    {
        auto foo = new Foo();
        foo.bar();
    }
}

質問:

  1. のようなものはwhoCalledMe存在しますか?もしそうなら、それは何と呼ばれていますか?
  2. 何かが存在する場合、コンパイル時に(テンプレートで)使用できますか?

あるいは;

  1. 実行時にコールスタックにアクセスできますか? phpのようにdebug_backtrace
4

3 に答える 3

5

Cyber​​Shadow の発言を拡張するには、 を使用して関数の完全修飾名を取得できるため__FUNCTION__、mixin を使用して関数をシンボルとして取得することもできます。

import std.stdio;
import std.typetuple;

void callee(string file=__FILE__, int line=__LINE__, string func=__FUNCTION__)()
{
    alias callerFunc = TypeTuple!(mixin(func))[0];
    static assert(&caller == &callerFunc);

    callerFunc();  // will eventually overflow the stack
}

void caller()
{
    callee();
}

void main()
{
    caller();
}

これらの 2 つの関数は相互に再帰的に無期限に呼び出すことになるため、スタックはここでオーバーフローします。

于 2013-08-13T19:25:45.253 に答える
2

呼び出し元を見つけることはデバッガーが行うことであり、通常、シンボリック デバッグ情報スイッチをオンにしてプログラムをビルドする必要があります。これを理解するためにデバッグ情報を読むことは、システムに大きく依存しており、かなり高度です。

例外アンワインド メカニズムも呼び出し元を検出しますが、これらのテーブルはそれらを必要としない関数に対しては生成されず、テーブルには関数の名前が含まれません。

于 2013-08-15T07:37:24.497 に答える