Technical explanation for discrepancy in uninitialized variable in Ada?

390 views Asked by At

As I understand it, an uninitialized variable in Ada is undefined, so it could be anything. Normally, the compiler keeps you from using an uninitialized variable, since this is silly. When playing around with shifting arrays, I noticed GNAT would let me access the now uninitialized members of the array. For a left shift the new rightmost member would be 0, and for a right shift the new leftmost member would be 6512352. This held true regardless of the size of the array, or how much it was shifted.

Is there a technical explanation for these numbers?

All testing was done on an Intel x64. My AMD x64 machines are down, and my RaspPi broke a few days ago.

Shift implementation:

function Shift(Source : in Static_Array;
               Toward : in Direction;
               By : in Positive := 1)
               return Static_Array is
    Result : Static_Array(Source'Range);
begin
    case Toward is
        when Left =>
            Result(Result'First .. Result'Last-By) :=
                Source(Source'First+By .. Source'Last);
        when Right =>
            Result(Result'First+By .. Result'Last) :=
                Source(Source'First .. Source'Last-By);
    end case;
    return Result;
end Shift;

In the test file:

A : Static_Array := (1, 2, 3, 4, 5, 6, 7, 8);

Results:

test results

The results were generated from a test program. First thing is what's being run, after → is the result, after = is what's "expected". Since the value is uninitialized and that's undefined, I just put 0 to have something.

1

There are 1 answers

4
trashgod On BEST ANSWER

Uninitialized array components contain whatever remnants were in memory before execution. The spurious values may appear stereotypical, due in part to the way the generated code allocates stack frames. A glance at the generated assembly source may be helpful. Changing the execution environment will usually change the outcome. I see distinct differences with various array sizes. Try varying the optimization level using -On. Use a platform-specific memory altering command, e.g. purge, to see the effect.