Integer subranges types are subranges of CARDINAL if they fit into the range of CARDINAL and no other base type is given. In the following example Range1 is compatible to CARDINAL while Range2 may be intermixed with INTEGERs in expressions:
TYPE Range1 = [1..10]; (* equivalent to CARDINAL [1..10] *) Range2 = INTEGER [1..10];
The Modula-2 reports in [PIM1] and [PIM3] state that TRUNC returns CARDINAL. This was a historical decision in favor of the Lilith architecture which is much less useful on all other common architectures. Later, in [PIM4], Wirth has revised this decision and TRUNC returns INTEGER since then. Many other implementors did this already in compilers which predate [PIM4] because INTEGER is much more useful as return type (and much easier to be implemented).
Usually this does not lead to portability problems in code which expects TRUNC to return CARDINAL because simple assignments like
cardinalNumber := TRUNC(realNumber);continue to work but will raise a run time error if realNumber turns out to be negative. However, expressions like
cardinalNumber1 := cardinalNumber2 + TRUNC(realNumber);are no longer valid but may be easily adapted by introducing the standard procedure ORD:
cardinalNumber1 := cardinalNumber2 + ORD(TRUNC(realNumber));Like in the previous example, ORD will raise a run time error in case of a negative argument. Note that the second form will be perfectly acceptable to those old compilers which still return CARDINAL.