変数への読み取り専用アクセスを提供することは、抽象化によって(もちろん)達成することができます。たとえば、変数をのの呼び出し可能なエンティティのモードパラメータまたはジェネリックにすることができます。これらの定数ビューによる変数の使用は、呼び出し可能なインスタンスまたは汎用インスタンスに限定されます。変数を読み込み専用にする方法はありますが、定数にすることはできません。
この構造は既存のプログラムに追加するのは容易ではないと私は思う。プログラムは既に構造化されているからだ。また、それは "読み取り専用"と構造の間の結合を必要とするため、独立した解決策ではありません。
別のオプションは、変数をprivateにして、その値を返す関数をエクスポートすることです。しかし、私は直接露出を望んでいました。 揮発性の定数であり、まだ異なる視点からの変数です。
私はオーバーレイを思い付いた:
with Interfaces;
package Read_Only is
subtype Pins is Interfaces.Unsigned_16;
V : constant Pins with Volatile, Import;
private
Backing : Pins with Volatile;
for V'Address use Backing'Address;
procedure Reset;
end Read_Only;
これはV
ので、パッケージ本体のみ(と子供を)シールドパッケージのクライアントがV
を読むことができますが、その値を変更することができます。しかし、このすべてを側面と住所の後ろに隠していると私は考えています。
編集:@ flyxさんのコメントで思い出しは、constant
が表示されますパッケージの公開部分のリーダーとはよくV
が物理的に定されていること、それはvolatile
であること、ないと思うことがあります。さらに、私はののオブジェクトのような文字をV
とし、それ以外の部分はRead_Only
から変更することはできません。 V
ここでは実際には定数オブジェクトではありませんが、その宣言ではそうです。私は、機能の不測の事態を招くことなく、認識可能な揮発性のオブジェクト、または何らかのオブジェクトの定数ビューを宣言したいと思います。
は、コンパイラが 'V'はそれがないので、あなたのコードを中断します' constant'、であるという事実に基づいて特定の最適化を行うことを許可されません実際に一定?私は、関数が最も良い方法であると言います。なぜなら、ユーザーとコンパイラの両方に値が時間とともに変化する可能性があることを通知するからです。 – flyx
** volatileの存在下でコンパイラがこれを最適化できるとは思っていませんが**可能な場合はコピーまたは参照を返す関数をインライン化することがありますが、揮発性変数のしかし、最適化はどのように**一定の**を取り除くことができますか?そのコンパイラはひどく壊れてしまいます。また、** volatile **はパッケージが 'Pure'になるのを防ぎます。一般的に、純粋なパッケージのように、Ada関数は実際に時間の経過とともに変化する価値の弱い指標です。しかし、それは質問または願いの一部です: "定数"≠ "読み取り専用"。 – B98
私は、「揮発性」は、おそらくは一定の伝播を禁止することに同意します。それはちょうど考えだった、私はLRMが暗記されていない。それにもかかわらず、私のGNATは*警告を出す:私がこれをするとき定数は変数をオーバーレイする*。 – flyx