Suppose I have declared some types
type ABC_TYPE is range 0 .. 7;
subtype AB_SUBTYPE is ABC_TYPE range 0 .. 3;
type DE_TYPE is range 1 .. 4;
what is the expected behavior of:
abc : ABC_TYPE := 7;
ab : AB_SUBTYPE := AB_SUBTYPE(abc);
de : DE_TYPE := DE_TYPE(abc);
when compiling without range checks?
As Jacob said, the result is not defined by the language. The most likely behavior is that the compiler will generate code that treats the values as integers with a certain "natural" range, and will simply copy the integers around as long as they fit into the range.
In your example:
type ABC_TYPE is range 0 .. 7;
subtype AB_SUBTYPE is ABC_TYPE range 0 .. 3;
type DE_TYPE is range 1 .. 4;
abc : ABC_TYPE := 7;
ab : AB_SUBTYPE := AB_SUBTYPE(abc);
de : DE_TYPE := DE_TYPE(abc);
On the most commonly used processors, the compiler will store the variables as a 1-, 2-, or 4-byte integer. The range of a 1-byte integer will be either 0..255 or -128..127--for this case, it doesn't really matter. So what will happen is that 7 will be stored in the 1-, 2-, or 4-byte integer allocated for de
. Then, when the program accesses de
, it most likely will just read that integer and work with it. I'd expect DE_TYPE'Image(de)
to work fine, because there is likely to be some low-level function that converts an "integer" to an image, that accepts any 32-bit (or 64-bit) integer as a parameter. Please note that I am not recommending you rely on this behavior. This is just what I think is most likely to happen given what I know about how compilers generate code. Note also that although ab
could be stored as a 2-bit integer, the compiler is unlikely to do so (except in a packed record or packed array) because it's not a natural integer size that processors can deal with.
In this case, though:
type ABC_TYPE is range 0 .. 10000;
subtype ABC_SUBTYPE is ABC_TYPE range 0 .. 100;
abc : ABC_TYPE := 1234;
ab : AB_SUBTYPE := AB_SUBTYPE(abc);
Now, it's possible that if range checking is suppressed, a compiler could truncate abc
to a byte before assigning it to ab
. This would happen by chopping off the upper byte, leaving 210, which means abc
would have the value 210 or -46 depending on whether the byte is treated as signed. (It's still out of range for an AB_SUBTYPE
, but since range checking is suppressed, that won't cause an exception.) Different compilers may have different behavior in this case.