0

組み込みシステムのコードを書いています。コンパイラはGCC派生物です。次のコードは正しいですか?

void *voidPointer = 0;
int (*functionPointer)(int a);

int testFunction(int a)
{
   return(a+1);
}

void registerFunction(void *pvFunctionAddress)
{
   voidPointer = pvFunctionAddress;
}

main()
{
   ...
   registerFunction(testFunction);
   functionPointer = voidPointer;
   x = functionPointer(17);
   ...
}

これで、xの値は18になります。コンパイラはエラーを表示しませんが、これは正しいですか?または、スタック上のメモリを上書きしますか?

ありがとう。

4

3 に答える 3

3

いいえ、厳密に言えばCはとvoid *関数ポインタ間の変換を禁止しているため、「正しい」ことは決してありません。

それが機能する場合、それは特定のコンパイラがその特定のターゲット(オペレーティングシステムとハードウェアの組み合わせ)に対してそれを許可しているためです。

于 2012-11-20T15:45:00.083 に答える
3

厳密に言えば、C標準によれば、avoid*は関数ポインタを保持できることが保証されていません。POSIXでは、void*(関数をサポートするためにdlsym())関数ポインターをに格納できる必要があると思います。https://stackoverflow.com/a/12359083/12711を参照してください

于 2012-11-20T15:45:41.643 に答える
0

次のように言いましょう。

C では、関数は、その実行を開始する適切なアセンブリ内の最初の命令のアドレスと呼び出し規則によって識別されます。したがって、void*呼び出し規則がコンパイル時の定数である場合、a はそれを格納する有効なストレージ クラスです。最も一般的に使用されている CPU アーキテクチャでは、そうです。

コードがターゲット ハードウェアのコンパイラで動作する場合は、その意味で正しいです。

簡単な比較を次に示します。

uintptr_t i = NULL;

uintptr_t(通常) は(タイプ)unsigned long intと同じストレージ クラスであるため、有効な C です。void *NULL

于 2012-11-20T16:06:51.187 に答える