0

私がこれを持っているとしましょう

typedef struct qwerty {
    void *f;
} qwerty_t;

そして私はこれをしたい

static qwerty_t x    = {
    .f = (void *)some_external_function
};

error: initializer element is not constant(正しく理解していれば)some_external_functionコンパイル時にの方向がわからないため、取得しています。

それがエラーの正しい説明でない場合は、その理由を説明してください。

.fまた、その関数の方向にどのように初期化できますか?

4

2 に答える 2

3

コメントから質問へ:

  1. some_external_function?の宣言を表示しません。たとえば、それ自体が実際の関数ではなく関数ポインターである場合、そのエラーが発生します。— <a href="https://stackoverflow.com/users/15168/jonathan-leffler">ジョナサン・レフラー

  2. 確かに、あなたは正しいです。私はまさにそれをしていました。—アレクサンダーンスト

決定的なものかどうかはわかりませんが... 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()

于 2013-09-14T00:33:16.713 に答える