13

バックグラウンド

POSIX 標準は、多くのライブラリ関数とその他の識別子を C 言語に追加します。関数の説明では、次のdlsym()ように述べています(強調して):

あらすじ

#include <dlfcn.h>

void *dlsym(void *restrict handle, const char *restrict name);

説明

dlsym () 関数は、シンボル (関数識別子またはデータ オブジェクト識別子)のアドレスを取得します...

void *C 標準では、関数ポインターを に変換できること、またはポインターのサイズが同じであることさえ保証されていません。これにより、C の型システムに追加の制限が効果的に追加されます。

質問

私の質問はこれです:

  • C の型システムのこの制限に対する規範的な参照はありますか、それとも特定のライブラリ関数の説明からのみ推測できますか?
  • POSIX はシステム上でも実装可能ですか? sizeof (function pointer) > sizeof (void *)

参考文献

4

1 に答える 1

7

dlsym () リファレンスには、変換は C 標準では定義されていませんが、準拠する実装ではこれが正しく機能する必要があると記載されています。したがって、これを機能させることができないシステムでは、準拠した実装ではなく、おそらくこれを文書化するでしょう:

次のように、void * ポインターから関数ポインターへの変換に注意してください。

fptr = (int (*)(int))dlsym(handle, "my_function");

ISO C 標準では定義されていません。この標準では、準拠する実装で正しく機能するために、この変換が必要です。

これについてC++ の観点から説明し、古いバージョンのdlsym() リファレンスにリンクし、より詳細な説明がある古い記事があります。

ISO C 標準では、関数へのポインタをデータへのポインタに前後にキャストできる必要はありません。実際、ISO C 標準では、タイプ void * のオブジェクトが関数へのポインターを保持できることを要求していません。ただし、XSI 拡張機能をサポートする実装では、タイプ void * のオブジェクトが関数へのポインターを保持できる必要があります。ただし、関数へのポインターを別のデータ型 (void * を除く) へのポインターに変換した結果は、まだ定義されていません。ISO C 標準に準拠するコンパイラは、次のように void * ポインターから関数ポインターへの変換が試行された場合に警告を生成する必要があることに注意してください。

fptr = (int (*)(int))dlsym(handle, "my_function");

ここに記載されている問題により、将来のバージョンでは関数ポインターを返す新しい関数が追加されるか、現在のインターフェイスが非推奨になり、データ ポインターを返す関数と関数ポインターを返す関数の 2 つの新しい関数が使用される可能性があります。

于 2014-12-30T14:41:37.507 に答える