Sequential_IO may be instantiated with either a definite (constrained) or indefinite (unconstrained) type.
For the definite type case, the elements written to the file are simply the memory images of the data values with no control information of any kind. The resulting file should be read using the same type, no validity checking is performed on input.
For the indefinite type case, the elements written consist of two
parts. First is the size of the data item, written as the memory image
Interfaces.C.size_t value, followed by the memory image of
the data value. The resulting file can only be read using the same
(unconstrained) type. Normal assignment checks are performed on these
read operations, and if these checks fail,
raised. In particular, in the array case, the lengths must match, and in
the variant record case, if the variable for a particular read operation
is constrained, the discriminants must match.
Note that it is not possible to use Sequential_IO to write variable
length array items, and then read the data back into different length
arrays. For example, the following will raise
package IO is new Sequential_IO (String); F : IO.File_Type; S : String (1..4); ... IO.Create (F) IO.Write (F, "hello!") IO.Reset (F, Mode=>In_File); IO.Read (F, S); Put_Line (S);
On some Ada implementations, this will print
hell, but the program is
clearly incorrect, since there is only one element in the file, and that
element is the string
In Ada 95 and Ada 2005, this kind of behavior can be legitimately achieved using Stream_IO, and this is the preferred mechanism. In particular, the above program fragment rewritten to use Stream_IO will work correctly.