10

関数ポインタをその関数に渡すことによって、ファイルの1つから関数を公開したいとします。その機能を次のように宣言しても安全staticですか?関数はそのファイルに固有であると宣言されているので、コンパイラーは私の関数ポインターを無効にする、またはそのファイルのコンテキスト外でそれを無意味にする柔道を行うことを許可されていますか?

私のコードではありませんが、私が言っていることの(ばかげた)例:

void    static   cool_function(void);
void    extern (*cool_function_ptr)(void); // Actually, I’m not sure of where the `extern` goes in a function-
                                           // pointer declaration. Damn you, confusing function-pointer syntax!

そのコード(またはその構文的に正しい近似)を考えるとcool_function_ptr、別のファイルからアクセスすることは違法でしょうか?

4

5 に答える 5

11

そうすることは完全に安全であり、しばしば役に立ちます。同じことがstatic変数とデータポインタにも当てはまります。コンパイラが、別の変換ユニットから関数ポインタを介して関数を呼び出す機能を妨げる可能性のある、凝った最適化(非標準の呼び出し規約、インライン化、リファクタリングなど)を実行する場合は、コンパイラの責任で次のことを決定します。関数のアドレスが取得されたり、コードの複数のバージョンが生成されたりすることはありません。そのうちの1つは、標準の呼び出し規約を使用して外部から安全に呼び出すことができます。

于 2011-02-28T04:59:30.173 に答える
3

もちろん。関数ポインタは単なるアドレスであり、魔法のようなものは何もありません。

次に例を示します。

$ cat Makefile
.PHONY: all
all:    main
        ./main
main:   main.c other.c 
        gcc -o main main.c other.c 
$ cat main.c
#include <stdio.h>

static void goodnight(){
  printf("Goonight, gracie!\n");
  return;
}

int
main(char * argv[], int argc){
  other(goodnight);
  return 0;
}
$ cat other.c
#include <stdio.h>

void other(void(*fp)()){
  fp();
  return ;
}
$ make
gcc -o main main.c other.c 
./main
Goonight, gracie!
$ 

難しいのは、関数へのポインタを使って関数の宣言を取得し、voidを正しく返すことです。

于 2011-02-28T04:56:33.690 に答える
1

あなたを噛むかもしれない唯一のことは、関数がインライン化されているかどうかです-そしてポインターのためにそれのアドレスを取ることはそれが起こらないようにするべきです。

これを行うと、発信者が完全な署名を知ることができなくなります。そのため、火遊びをしていて、物事が一列に並ぶことを望んでいます。

そして、それは「externvoid」と「staticvoid」です-ストレージクラス、そしてタイプを返します。

于 2011-02-28T04:58:39.387 に答える
1

静的関数へのポインタについては何も違いはありません。

ただし、ポインタを渡すことは、ポインタを直接呼び出すことを許可するよりも少し効率が悪い場合があります。なぜそうしているのかは私には完全にはわかりませんでしたが、私にはあまり意味がありませんでした。

于 2011-02-28T04:59:29.440 に答える
1

絶対に許可され、潜在的に完全に合理的


この言語を使用すると、モジュールの外部にある静的関数へのポインターを渡すことができます。

したがって、モジュール内呼び出しをコンパイルする際にコンパイラーが行う可能性のあるトリックは、何らかの形で実行しているものと互換性がある必要があります。

一般に、関数をグローバルにすることに関しては、実際には良いコードパターンだと思います。これは、関数を追加でカプセル化するためです。ただし、外部参照のない単純な静的関数に関しては反対の議論をすることもできます。

全体として、重要なのはオブジェクトとアプリケーションの設計であり、静的関数をグローバルに参照するかどうかではないと思います。

于 2011-02-28T05:01:38.827 に答える