2013-06-12 17 views
7

内モジュラータイプの定義:はなぜこの仕事doesntの、簡潔で一般的なパッケージ

generic 
    Max : in Positive; 
package Modular_Gen_Issue is 
    procedure Foo; 
private 
    type Mod_Thing is mod Max; -- NOK 
    type Int_Thing is new Integer range 0 .. Max; -- OK 

end Modular_Gen_Issue; 

コンパイルすると:

$ gnatmake modular_gen_issue.ads 
gcc-4.4 -c modular_gen_issue.ads 
modular_gen_issue.ads:6:26: non-static expression used for modular type bound 
modular_gen_issue.ads:6:26: "Max" is not static constant or named number (RM 4.9(5)) 
gnatmake: "modular_gen_issue.ads" compilation error 
$ 

どのように私は、単一の番号を渡すと定義するためにそれを使用することができますモジュラータイプ?

はい、モジュラータイプにする必要があります。

+1

これでちょっとやってしまったあと、どうしたらいいか知りたい! :-)ここに喜びがないなら、少なくともcomp.lang.adaを試してみてください。少なくとも、そこにいる言語弁護士からの理由を得るためです。 –

答えて

10

申し訳ございません。モジュラ型を宣言するときはいつでも、モジュラスは静的な値でなければなりません。つまり、コンパイラはその値をすぐに把握することができます。そして、これは動作しません。これは型宣言の多くの部分に当てはまります。特に、オブジェクトの必要なビット数やオブジェクトの表現に関するその他の特徴を理解するためにコンパイラが必要とする部分です。一方、Int_Thingでは、範囲の上限は静的である必要はありません(コンパイラは、Int_ThingがIntegerと同じであることを既に知っており、範囲は境界チェックに使用されますが使用されませんInt_Thingの大きさを判断する)。

これが現実の状況であり、あなたが様々なモジュラータイプを扱うことができる汎用のが必要な場合は、モジュラー型自体ジェネリックパラメータ作ることができるかもしれません:

generic 
    type Mod_Thing is mod <>; 
package Modular_Gen_Issue is ... 

(PS Mod_Thingの範囲をあなたの例では0..MAX-1、ない0..MAXだろう)書いたものAJB、あなたの一般的なパッケージの以下の使用を検討することに加えて、

+0

コンパイラは正の数とその上限(max)を知っており、モジュラ型の下限が0であることを知っているので、これはint_thingの例とはまったく異なっています。 – NWS

+3

コンパイラは、型宣言を参照するポイントの上限(max)を認識しません。これは、汎用および指定されたmax値をインスタンス化していないためです。そして、それをインスタンス化する前にジェネリックを最初に処理しているときにこれを知る必要があります。ジェネリックスはCマクロと似ていません。マクロを展開するまで、テキストは保存され、テキストは表示されません。ジェネリックスは、インスタンス化する前でもルールに従わなければなりません。 – ajb

+2

もう1つのコメント:Int_Thingとの大きな違いは、Int_Thingは既存の型(Integer)から派生し、コンパイラはその型のサイズを派生されたものと同じにすることです。 '0 .. Max'は境界チェックを追加しますが、サイズは変更しません。しかし、まったく新しい非派生型を作成する場合、コンパイラはサイズを静的にする情報を必要とします。あなたが 'タイプInt_Thingが範囲0 ..マックス'であると言えば、それも違法でしょう。 – ajb

3

:。ここでは、

procedure Foo (Bar : in Positive) is 
    package Instance is new Modular_Gen_Issue (Max => Bar); 
begin 
    null; 
end Foo; 

をパッケージInstanceは、すべての呼び出しで変更される非静的な値で作成されます。Foo Adaではこれが許可されているため、コンパイラーはジェネリックユニットのどのパラメーターも静的でないと期待する必要があります。だから静的な値でパッケージをインスタンス化することはできますが、そこにモジュール型を宣言することはできません。 AJBの提案を拡張

、あなたが行うことができます:

generic 
    type Mod_Thing_Base is mod <>; 
package Modular_Gen_Issue is 
    type Mod_Thing is new Mod_Thing_Base; 
end Modular_Gen_Issue; 

この方法で、あなたは(あなたが直接パラメータとしてそれを取ることによって行うことができませんでした)Mod_Thingの基本操作を定義することができます。

関連する問題