ねえ、私はソフトウェアをより安全でより柔軟にするという観点から、現実の世界でどのようにvoidポインタが適用されるのか疑問に思っています。たとえば、voidポインター、つまりそれがキャストするポインターは外部に隠されていることを知っています。これにより、ソフトウェアがより安全になります。voidポインタを使用する他の理由はありますか?
4 に答える
ボイドポインタは、ソフトウェアをこれ以上安全にしません。
cでvoid*を使用する理由は、ポリモーフィズムの形式です。データのタイプがわからない場合は、void*を渡すことができます。
C ++では、void *を使用する必要が少なく、言語によってCの使用の一部が妨げられます
たとえば、voidポインター、つまりそれがキャストするポインターは外部に隠されていることを知っています。これにより、ソフトウェアがより安全になります。
コンパイルされると、型はより高いレベルの概念であるため、ポインタの型を明らかにするアセンブリコードには露骨なものは何もありません。アセンブリコードにはレジスタ幅しかありません。(理論的には、アセンブリコードを調べることで、データ型のサイズとさまざまなフィールドの用途を推測できますが、voidポインターを使用しても、それは変わりません。しかし、私は逸脱します。)
そうは言っても、「外部」がポインタタイプを知る唯一の他の方法は、提供するAPIを介することです(おそらくヘッダーファイルを介して)。しかし、それはAPIを持つことの利点の1つです。他の誰かがあなたにポインターを渡せるようにすることは、あなたがその型を内部で使用することを絶対に保証するものではありません。
あなたがそれを言うように使うためにCでさえ言い訳はありませんvoid*
。これは、不完全な型へのポインタを使用して行う方がはるかに適切です。
typedef struct myInternal myInternal;
myInternal* getIt(void);
int doIt(myInternal*);
これにより、内部構造/実装をユーザーに隠すのと同じ効果があります。しかし、それを使ったプログラミングははるかに簡単であり、特にユーザーはそのような異なる不透明なインターフェースを混同することはできません。
void *を使用する一般的な理由は、API/ライブラリのユーザーにコンテキストを提供することです。提供されるコンテキストは多くの場合ポインタであり、void*はそれを不透明にします。ライブラリ開発者が抱える問題は、void*が戻されたときにそれを検証することです。これは非常に難しい場合があります。実際、ライブラリは、内部データを公開しなくてもより簡単に検証できる識別子をユーザーに提供したほうがよいでしょう。
つまり、void *の使用を考えている場合は、使用しないでください。