web-dev-qa-db-ja.com

C ++ポインター:インダイレクションのレベル数

レガシーCコードを含まないC++プログラムで、ソースコードで使用する必要がある間接参照のレベルの最大数に関するガイドラインはありますか? Cでは(C++ではなく)Cで、多次元配列のポインターへのポインターを使用しているプログラマーがいますが、配列の場合、ポインターへのポインターを回避するために使用できるC++のデータ構造があります。

まだポインター(またはこれ以上)へのポインターを作成しているユーザーは、パフォーマンスETCのためだけにポインターへのポインターを使用しようとしていますか?理由は?

ポインターを変更する必要がある場合にのみ、ポインターへのポインター以外は使用しないようにしました。誰かが間接レベルの数に関して他の公式または非公式のガイドラインやルールを持っていますか?

3
A B

間接参照に関するガイドラインや実際的な制限はありません。ずさんなデザインを示すケースで、いくつかのレベルの間接参照を定期的に処理しているのでない限り、このような制約を配置する理由はありません。

つまり、4、5、6、またはそれ以上のレベルの間接参照が予想される有効なケースがありますが、これらはまれであり、誰かがひどいことをしない限り、通常はコードに表示されません。採用されている間接参照のレベル。

たとえば、3レベル以上の間接参照を使用している場合は、アーキテクチャを変更する必要があるかどうかを検討する必要があります。

しかし、これは、3レベルを超える間接参照を許可してはならないという意味ですか?絶対違う。それは単に、それが可能性がある可能性がある指示である可能性があることを意味しますおそらくコードのアーキテクチャに固有の非効率性がある可能性があります。これ以上何もない。 (そのステートメントの意図的な曖昧さには注意してください。それは、必ずしも実際の問題ではなく、問題を引き起こす可能性がある何かの単なる可能性です。)

6
greyfade

42要素のリンクリストには、最後の要素にアクセスするための42レベルの間接参照が含まれていることに注意してください。 1要素のリストの要素に到達するには、単一の間接参照を使用します。リストへのポインターを指定すると、p->dataのようなことを行います。 2番目の要素に到達するには、2つの間接参照が必要です:p->next->data。各矢印は間接です。ただし、表記は****の単なる行ではありません。もちろん、p->nextは実際には(*p).nextです。したがって、(*(*(*p).next).next).dataと書くことができます。あなたが42のアスタリスクを見たいならば、それは収容することができます。

リンクリストのnextフィールドが構造体の先頭にある場合、マシンレベルでは実際には(***...***p).dataと同等であり、dataへの最終アクセスのみがオフセットを使用します。

そしてもちろん、ツリー構造には多くのレベルの間接参照が含まれます。特に、バイナリサーチツリーのようにファンアウトが低い場合、特に不均衡になることが許可されている場合はそうです。

2
Kaz

MISRA C++:2008によると、ルール5-0-19:

オブジェクトの宣言には、2レベル以下のポインター間接化が含まれます。

それは宣言の制限にすぎませんが。それでも、任意の数の間接参照を通じて変数にアクセスできます。

0
jinawee

特定の瞬間に複数のレベルの間接参照を持つコードを書くことが実際に良い考えであることは非常にまれです。

これの一部は、慎重を期すために、逆参照する前にすべてのポインターをNULLについてチェックするように指示しているためであり、複数レベルの間接参照を記述する場合は困難です。

これの一部は、最新のプロセッサには複雑なデータキャッシュとさらに複雑なメモリ割り当てスキームがあり、複数のレベルの間接参照(長いポインターチェーンを介して)を歩くと、キャッシュから聖なるがらくたになる可能性があるためです。

特定の方法でキャッシュをスラッシュすると、誤った結果をもたらす可能性のあるプロセッサーを見てきました。 (はい、これらはハードウェアの問題です。いいえ、ベンダーはすぐにそれらを修正するつもりはありません。いずれにしても、それらのチップはすでにフィールドに出ています。)私は、これらのいずれかのようなにおいがする問題を個人的に修正しました参照の局所性に非常に注意するようにコードを書き直すことにより、メーカーがこのような問題についてすでに警告しているプロセッサ。 (キャッシュのスラッシュが疑われたため、私は書き換えを行いませんでした。後でこの問題を発見しました。元のコードがスパゲッティとポインターへのポインターへのポインターの判読不能な山だったため、書き換えを行いました。問題が発生したとき、少し混乱しました私は消えてしまったところを素早く静かに追いかけていた)

そして、その一部は、1レベルの間接化のみを実行しているコードは、通常、貧弱なメンテナンスschlubが理解するのに非常に簡単だからです。

0
John R. Strohm