29

intptr_tの代わりに汎用ストレージ (ポインターと整数値を保持するため) として使用することをお勧めしますvoid*か? (ここで見られるように: http://www.crystalspace3d.org/docs/online/manual/Api1_005f0-64_002dBit-Portability-Changes.html )

私がすでに読んだことについて:

  • int-> void*->intラウンドトリップは元の値を保持するとは限りません。私は推測するint-> intptr_t->intするだろう
  • 両方のポインター演算void*intptr_tキャストが必要なため、ここでは利点がありません
  • void*ポインタを格納するときの明示的なキャストが少ないことをintptr_t意味し、整数値を格納するときのキャストが少ないことを意味します
  • intptr_tC99が必要

他に何を考慮する必要がありますか?

4

2 に答える 2

32

intptr_tの代わりに汎用ストレージ (ポインターと整数値を保持するため) として使用することをお勧めしますvoid*か?

いいえ。

intptr_t存在する保証はありません。まず、ご指摘のとおり、C99 で導入されました。第 2 に、実装は、情報を失うことなく変換されたポインター値を保持するのに十分な大きさの整数型を持つ必要はありません。

を に変換しintintptr_t元に戻すと、情報が失われる可能性intptr_tはほとんどありませんが、よりも広いという実際の保証はありませんint

ポインター値を格納する場合は、ポインター オブジェクトに格納します。それがポインタオブジェクトの目的です。

オブジェクトまたは不完全な型へのポインターはvoid*、情報を失うことなく変換して元に戻すことができます。関数へのポインターにはそのような保証はありませんが、関数へのポインターの型は、情報を失うことなく、他の関数へのポインターの型に変換して元に戻すことができます。(私は C 標準について言及しています。POSIX はいくつかの追加の保証を提供していると思います。)

整数値またはポインター値を同じオブジェクトに格納する場合、最初にすべきことは、設計を再考することです。すでにそうしており、本当にこれをやりたいと結論付けた場合は、共用体の使用を検討してください (そして、最近保存した値の種類を注意深く追跡してください)。

void*引数を使用して任意のデータを渡すことができるAPI があります。たとえば、POSIXpthread_create()関数を参照してください。これは整数値をキャストすることで悪用される可能性がありますが、整数オブジェクトのアドレスvoid*を渡す方が安全です。

于 2012-02-29T02:47:00.233 に答える
7

いいえ、特定の型がポインターと整数の両方を格納する合理的な方法であるとは保証できません。さらに、コードが混乱します。もっと良い方法があります。

整数とポインタを同じオブジェクトに格納したい場合、クリーンでポータブルな方法は共用体を使用することです:

union foo {
   int integer_foo;
   void *pointer_foo;
};

これは持ち運び可能で、2 つのうち大きい方に必要なサイズのストレージに両方の種類のものを保管できます。常に動作することが保証されています。

于 2012-02-29T03:04:53.760 に答える