Defining a modular type in a common package

In short, why this does not work:

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; 

With compilation:

 $ 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 $ 

How can I pass one number and use it to determine the modular type?

And yes, it must be a modular type!

+7
source share
2 answers

Sorry, you can’t. Whenever you declare a modular type, the module must be a static value, i.e. A value that the compiler can immediately determine there. And it does not work. This applies to many parts of type declarations, especially those parts that the compiler needs to figure out how many bits an object needs, or other functions that represent the object. In Int_Thing, on the other hand, the upper bound of the range does not have to be static (the compiler already knows that Int_Thing will be displayed just like Integer, and the range is used to check the bounds, but it is not used to determine how large Int_Thing will be).

If this is a real situation, and you need a generic type that can handle various modular types, you can make the modular type itself a generic parameter:

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

(PS The range of Mod_Thing in your example will be 0..Max-1, not 0..Max.)

+10
source

In addition to what ajb wrote, consider the following use of your generic package:

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

Here, the Instance package is created with a non-static value that can change with every call to Foo . Because Ada allows this, the compiler should expect that any parameter of the universal device will be unsteady. This is why you cannot declare your modular type there, although you can instantiate your package with a static value.

Ajb offer extension, you can do:

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

Thus, you can define primitive Mod_Thing operations (which you could not do by taking it directly as a parameter).

+3
source

All Articles