2

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.

Patrick Kelly
  • 633
  • 5
  • 22
  • Please edit your question to include a [complete example](http://stackoverflow.com/help/mcve) that exhibits the problem you describe. – trashgod Jun 23 '15 at 21:19
  • Done. This isn't a problem though. I'm just curious if there is a technical explanation for why those numbers. 0 makes a lot of sense, 6525536 doesn't. – Patrick Kelly Jun 24 '15 at 00:33
  • Ah, I thought you were shifting in place; more below. – trashgod Jun 24 '15 at 02:39
  • Functional implementation was easier. :P Gonna do a procedural implementation after. Might be interesting to compare the results of erroneous members; I'd expect an inplace shift to keep the old value though. – Patrick Kelly Jun 24 '15 at 18:04

1 Answers1

2

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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I did play around a bit with optimization levels, different compiler builds, different OS's, and even different Intel x64's, which is why I found it very curious the number was always 6525536. I think I might know what it is, but until I can confirm specifically, I'll hold off on a detailed answer. – Patrick Kelly Jun 24 '15 at 18:02
  • I see a slightly different value each time for `A(1)` on `Shift(A, Right, 1)`. Anything special about `6525536=16#00639260#`? If you see anything dispositive, I'll try to duplicate it for my platform's ABI. – trashgod Jun 24 '15 at 22:36
  • A close inspection of the assembly, including how the memory changes were occurring when other scheduled programs were being executed, resulted in me having absolutely no idea where 6525536 came from. I'm considering it a curious fluke unless someone can figured it out. – Patrick Kelly Jun 26 '15 at 16:11
  • I suspect the remnants are from a previous stack frame, perhaps even a previous program. Any pattern is likely characteristic of the platform's [ABI](https://en.wikipedia.org/wiki/Application_binary_interface). – trashgod Jun 26 '15 at 16:41