• Did I find a (nearly-)gotcha here?

    From reinert@21:1/5 to All on Fri Nov 12 23:46:09 2021
    Hello,

    Assume the following program:

    with Text_Io; use Text_Io;
    procedure test2 is
    procedure test_a(ok : out Boolean) is
    begin
    if false then
    ok := true;
    end if;
    end test_a;
    procedure test_b(ok : in out Boolean) is
    begin
    if false then
    ok := true;
    end if;
    end test_b;
    ok_a,ok_b : Boolean := true;
    begin
    test_a(ok_a);
    test_b(ok_b);
    Put_Line("ok_a = " & ok_a'Image);
    Put_Line("ok_b = " & ok_b'Image);
    end test2;

    I get the following output (using GNAT Community Edition):

    ok_a = FALSE
    ok_b = TRUE

    As far as I understand, this is correct.
    However, I think I remember that (some) older versions of the GNAT compiler gave a different result. Could others try? And does my program example reveal an unnecessary gotcha?

    reinert

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rod Kay@21:1/5 to reinert on Sat Nov 13 19:53:57 2021
    On 13/11/21 18:46, reinert wrote:

    procedure test_a(ok : out Boolean) is
    begin
    if false then
    ok := true;
    end if;
    end test_a;

    I get the following output (using GNAT Community Edition):

    ok_a = FALSE
    ok_b = TRUE

    As far as I understand, this is correct.
    However, I think I remember that (some) older versions of the GNAT compiler gave a different result. Could others try? And does my program example reveal an unnecessary gotcha?

    reinert


    Hi reinert,

    The value of an 'out' only parameter needs to be explicitly set. The initial value of the 'ok_a' variable will be discarded and then set to
    the value of the 'ok' parameter within 'test_a' when the call completes.
    Since 'ok' is not set in 'test_a' it's value is indeterminate (and
    therefore erroneous).

    I'd expect GNAT to issue a warning. Probably you need to add a flag
    to GNAT to enable that warning. Perhaps try adding '-gnatwa'.


    Regards.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Niklas Holsti@21:1/5 to reinert on Sat Nov 13 10:52:26 2021
    On 2021-11-13 9:46, reinert wrote:
    Hello,

    Assume the following program:

    with Text_Io; use Text_Io;
    procedure test2 is
    procedure test_a(ok : out Boolean) is
    begin
    if false then
    ok := true;
    end if;
    end test_a;
    procedure test_b(ok : in out Boolean) is
    begin
    if false then
    ok := true;
    end if;
    end test_b;
    ok_a,ok_b : Boolean := true;
    begin
    test_a(ok_a);
    test_b(ok_b);
    Put_Line("ok_a = " & ok_a'Image);
    Put_Line("ok_b = " & ok_b'Image);
    end test2;

    I get the following output (using GNAT Community Edition):

    ok_a = FALSE
    ok_b = TRUE

    As far as I understand, this is correct.


    The value of ok_b is correct.

    The value of ok_a is not defined by the language, I believe. The
    parameter test_a.ok is passed by copy-out (but not copy-in), and is not assigned a value in test_a, therefore the returned value comes from an uninitialized local Boolean, and is undefined.


    However, I think I remember that (some) older versions of the GNAT
    compiler gave a different result.

    That may be so, but it would not be bug in GNAT. It is a programmer error.


    And does my program example reveal an unnecessary gotcha?


    The gotcha is that Ada and GNAT do not detect all uses of uninitialized variables. That is regrettable, but it would be very expensive to detect
    them.

    Note that if the "out" parameter has a constrained subtype, say Integer
    range 1 .. 10, and is not assigned a value in the subprogram, a Constraint_Error may be raised on return if the uninitialized value
    fails the subtype check in the copy-out. (This has happened to me, when
    I was younger and perhaps less learned.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From G.B.@21:1/5 to Rod Kay on Sun Nov 14 09:25:45 2021
    On 13.11.21 09:53, Rod Kay wrote:
    On 13/11/21 18:46, reinert wrote:

        procedure test_a(ok :    out Boolean) is
        begin
           if false then
              ok := true;
           end if;
        end test_a;

    However, I think I remember that (some) older versions of the GNAT compiler gave a different result. Could others try?  And does my program example reveal an unnecessary gotcha?

       I'd expect GNAT to issue a warning. Probably you need to add a flag to GNAT to enable that warning. Perhaps try adding '-gnatwa'.

    GCC's -Wuninitialized does as Rod Kay says.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)