コメントから質問へ:
some_external_function
?の宣言を表示しません。たとえば、それ自体が実際の関数ではなく関数ポインターである場合、そのエラーが発生します。— <a href="https://stackoverflow.com/users/15168/jonathan-leffler">ジョナサン・レフラー
確かに、あなたは正しいです。私はまさにそれをしていました。—アレクサンダーンスト
決定的なものかどうかはわかりませんが... Mac OS X 10.8.4 上の GCC 4.8.1 は次のコードを受け入れます:
extern int some_external_function(int, int);
typedef struct qwerty {
void *f;
} qwerty_t;
static qwerty_t x = {
.f = (void *)some_external_function
};
int main(void)
{
int i = 1;
int j = 2;
int (*f)(int, int) = (int (*)(int, int))x.f;
return f(i, j);
}
int some_external_function(int i, int j)
{
return i + j;
}
このように 'extra fussy' をコンパイルすると、いくつかの警告が表示されます:
$ gcc -std=c99 -Wall -Wextra -pedantic fp.c -o fp
fp.c:8:14: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
.f = (void *)some_external_function
^
fp.c: In function ‘main’:
fp.c:15:26: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
int (*f)(int, int) = (int (*)(int, int))x.f;
^
$
警告は非常に正確ですが、POSIX では、関数ポインターのサイズはデータ ポインターのサイズと同じでなければならないと規定されています (一方、C 標準では異なることを許可しています)。がなければ-pedantic
、警告はありません。
コードをと の定義を持つファイルと のx
定義を持つファイルの 2 つのファイルに分割し、コンパイルとリンクを行っても、エラーや新しい警告は発生しません。main()
some_external_function()