func_tその型を返す関数型を宣言することは可能func_tですか?
つまり、関数が自分自身を返すことは可能ですか?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
それともvoid *、型キャストを使用する必要がありますか?
構造体を使用した可能な解決策:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
でコンパイルしてgcc -Wallも警告は出ませんでしたが、これが 100% 移植可能かどうかはわかりません。
いいえ、C で再帰関数型を宣言することはできません。構造体 (または共用体) 内を除いて、C で再帰型を宣言することはできません。
void *解決策として、関数void *へのポインターではなく、オブジェクトへのポインターのみを保持することが保証されています。関数ポインターを変換できvoid *、拡張機能としてのみ使用できます。
関数ポインターをキャストすることはできませんvoid*(サイズが異なる可能性があります) が、別の関数ポインター型にキャストしてキャストし直して元の値を取得できるため、これは問題ではありません。
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
出力:
Called a function
Called a function
Called a function
つまり、関数が自分自身を返すことは可能ですか?
「それ自体」の意味によって異なります。それ自体へのポインターを意味する場合、答えはイエスです! 関数がその型を返すことはできませんが、関数はそれ自体へのポインターを返すことができ、このポインターは呼び出す前に適切な型に変換できます。
詳細は質問comp.lang.c faq: Function that can return a pointer to a function of the same type. で説明されています。
詳細については、私の回答を確認してください。
関数定義を仮定する
T f(void)
{
return &f;
}
f()型の値を返しますTが、式の型&fは「関数を返すポインタT」です。何であれT、式&fは常に異なる、互換性のないtypeになりT (*)(void)ます。Tが のような関数へのポインタ型であってもQ (*)(void)、式&fは「関数へのポインタを返す-関数へのポインタ」またはQ (*(*)(void))(void).
が関数Tポインタ値を保持するのに十分な大きさの整数型であり、プラットフォーム上でとの間の変換T (*)(void)が意味を持つ場合、T次のような方法で回避できる可能性があります。T (*)(void)
T f(void)
{
return (T) &f;
}
しかし、それがまったく機能しない状況が少なくともいくつか考えられます。正直なところ、ルックアップ テーブルのようなものを使用する場合に比べて、その有用性は非常に限られています。
C は関数を他のデータ項目のように扱うようには設計されておらず、関数へのポインターはオブジェクト型へのポインターと交換できません。
このようなものはどうですか:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
方法があります。これを試してみてください:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
C++ を使用している場合は、参照またはポインターによってオブジェクト型を返すStateを宣言するオブジェクト型を作成できます(ステート マシンの使用例を想定)。次に、各状態を の派生クラスとして定義し、 の実装から適切な他の派生型をそれぞれ返すことができます。operator()StateStateoperator()