4

関数の関数ポインターtypedefを宣言する代わりに、関数宣言から取得することは可能ですか?

通常、

int foo(int x);
typedef int (*fooFunc)(int);
fooFunc aFunc;

私が欲しいもの:

int foo(int x);
foo* aFunc;

dlsymに使用したい:

foo* aFunc;
aFunc = dlsym(lib, "foo");
aFunc(x);

fooを更新してfooFuncを更新するのを忘れた場合、またはその逆の場合、それは悪いことです。また、私は多くの関数を持っている可能性があり、それらの関数に関連付けられている関数宣言と関数ポインターtypedefの両方を維持するのはより多くの作業になります。

結論:AndreyTの答えは最も移植性がありますが、gccをコーディングする場合は、typeofが優れたソリューションです。

4

5 に答える 5

6

特に宣言、つまり関数の非定義宣言について話している場合は、関数型のtypedef-nameを定義し、両方の場合にそれを使用して、関数自体を宣言し、ポインターを宣言することで、冗長性を取り除くことができます。それに、このように

typedef int FuncType(int); /* <- function type */
FuncType foo; /* <- declaration of `int foo(int)` */
FuncType *aFunc; /* <- definition of `int (*aFunc)(int)` */

つまり、typedef-namesは、非定義関数宣言で使用できます。ただし、関数定義でtypedef名を使用することはできません。つまり、後で行う必要があります。

int foo(int x) /* <- no way to use the above `FuncType` here */
{
  /* whatever */
}

これは基本的に上記のトリックを事実上役に立たないものにします。

もちろん、これは、既存の変更不可能な関数宣言からポインターを生成するのに役立ちません(それがあなたの状況である場合)。

于 2009-11-04T17:12:03.780 に答える
5

gccを持っている場合、typeofは機能します。

アップデート

$ cat fxf.c
#include <stdio.h>

int main(int argc, char **argv) {
  typedef __typeof__ (main) function_of_same_type_as_main_t;
  function_of_same_type_as_main_t *f;

  printf("main() called.\n");
  f = main;
  if (argc) f(0, NULL);
  return 0;
}
$ / usr / bin / gcc -std = c89 -pedantic -Wall -Wextra -o fxf fxf.c
fxf.c:3:警告:未使用のパラメーター'argv'
$ ./fxf
main()が呼び出されました。
main()が呼び出されました。
于 2009-11-04T17:03:29.983 に答える
2

簡単な答え:いいえ、それは機能しません。プロトタイプ()を持つfoo特定int (int)関数です。あなたがしたように使用することは、別のものを宣言するためにをfoo使用することに少し似ています:intint

4 x; // expect this to be the same as int x

そうは言っても、それを機能させるコンパイラ拡張機能があるかもしれません。今後のC++標準には、decltypeそれを可能にするキーワードが含まれることを私は知っています。これを使用すると、次のことが機能する可能性があります(サポートするコンパイラが手元にないため、テストされていません)。

int foo(int x);

decltype(&foo) aFunc = dlsym(lib, "foo");
于 2009-11-04T16:49:29.473 に答える
0

それは不可能。ただし、タイプの不一致を検出できるように、警告を生成するコードを記述できます。次のコードは、互換性のないポインタ型の警告から割り当てを生成します。

#include <stdio.h>

int foo(int, int);
typedef  int(*fooFunc)(int);

fooFunc myfunc;

int foo(int x, int y)
{
    return 2*x + y;
}

int main(int argc, char **argv)
{
    myfunc = foo;
    printf("myfunc : 0x%x\n", (unsigned int)myfunc);
    return 0;
}

もちろん、これはfoo関数が表示されている場所にこのテストコードを記述する必要があることを意味します。したがって、これは関数の型ごとに追加するコードがさらに多くなります。ここでの解決策はおそらくコードジェネレーターであり、関数とそれに関連するtypedefの両方を含む適切なヘッダーファイルを生成します。

于 2009-11-04T17:19:57.540 に答える
0

まったく同じではありませんが、関数をtypedefして、プロトタイプとポインターの両方に使用できます。

typedef int fooFunc(int);
fooFunc foo;
fooFunc *aFunc;
于 2009-11-04T17:38:37.597 に答える