comp.lang.ada
 help / color / mirror / Atom feed
From: Robert A Duff <bobduff@shell01.TheWorld.com>
Subject: Re: Ada style of passing 'in' parameters considered dangerous?
Date: Sun, 9 Feb 2003 02:01:42 GMT
Date: 2003-02-09T02:01:42+00:00	[thread overview]
Message-ID: <wcc3cmyw6t5.fsf@shell01.TheWorld.com> (raw)
In-Reply-To: 86isvuzabx.fsf@hoastest1-8c.hoasnet.inet.fi

Antti Sykari <jsykari@gamma.hut.fi> writes:

> Hello,
> 
> I recently asked in comp.compilers advice about implementing a
> parameter passing policy for a rather close-to-machine language.

Yes, I saw that thread.

The problem with this Ada rule is that it violates abstraction.
You don't know whose responsibility it is to worry about aliases
-- the caller or callee.

>...My
> suggestion for the method of passing 'in' parameters to procedures
> was:  Pass everything as readonly by default, and leave the
> by-reference/by-copy decision to the compiler.
> 
> It was pointed out that Ada already has this kind of policy.  In one
> reply (<03-01-169@comp.compilers>), it was mentioned that it is a
> time-bomb in Ada, since it permits the programmer to write code that
> is erroneous but the compiler cannot detect this.  Indeed, the
> standard ([1]) says that if an object has been passed via an
> unspecified parameter passing mechanism, is written via one access
> path and read via another, "possible consequences are that
> Program_Error is raised, or the newly assigned value is read, or some
> old value of the object is read".
> 
> For example, in the simplest case, a procedure can take a readonly
> 'in' argument "arg1" of type X, and an "in out" argument of the same
> type. Then, if it writes in arg2 and after that reads arg1, this might
> cause a run-time error or other implementation-defined behavior -- but
> only if the procedure is called with two identical arguments.
> 
> Of course, the erroneous behavior might occur in a more subtle way,
> which is not expected to happen.  I just can't think of any realistic
> example where this undefinedness would really hurt.

How about this example:

We have a record representing fractions of whole numbers:

    type Fraction is
        record
            Numerator: Integer;
            Denominator: Positive;
        end record;

    procedure Reciprocal(Result: out Fraction; X: Fraction);
    -- Sets Result to the reciprocal of X.

    procedure Reciprocal(Result: out Fraction; X: Fraction) is
    begin
        if X.Numerator > 0 then
            Result.Numerator := X.Denominator;
            Result.Denominator := X.Numerator;
        ... etc

It seems reasonable (without seeing the body of Reciprocal) to do:

    Reciprocal(Foo, Foo);

If Fractions are passed by copy (which is probably most efficient, since
they fit in just two registers), then it works fine.  If they're passed
by reference, we get the wrong answer.

Of course Reciprocal could be written to avoid the problem (e.g. write
it as a function instead).  That would be less efficient in the
non-alaised case.  But the Ada RM does not make it clear whose
responsibility this problem is -- the caller or the callee.  In Fortran,
the *call* would be wrong.

> My concerns here are:
> 
> - Is this generally considered a dangerous thing in Ada (or in
>   general)?

I consider it a problem in Ada.  But many other languages are worse in
this regard.

> - Have you encountered a non-trivial real-life case where the
>   programmer has shot himself in the foot in the form of
>   implementation-defined behavior because of the error mentioned above?
>   I'd be interested to hear of any such cases.

I don't know.  I would feel more comfortable if one could *prove* that
such things can't happen.

> - If there are such cases, could it have been prevented by having
>   different policy in the language?

Yes.

>...Do you think it would've been
>   better to force the programmer to specify the parameter passing
>   mechanism, for example?

There are drawbacks to that, too:

    - One normally wants the most efficient mechanism, which depends on
      the sizes of the parameters wrt register size.  But that's machine
      dependent, so the compiler ought to deal with it.

    - You can't (efficiently) pass components of packed records by
      reference.  The Pascal rule in this regard is ugly.  (Similar
      issue: slices of arrays.)

One possible solution is to disallow cases that might be aliased.  But
that would require more information than is available to an Ada compiler
-- it would need to know about global variables referenced by each
procedure, for example.

- Bob



  parent reply	other threads:[~2003-02-09  2:01 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-08 22:24 Ada style of passing 'in' parameters considered dangerous? Antti Sykari
2003-02-09  0:41 ` James S. Rogers
2003-02-09  2:11   ` Robert A Duff
2003-02-09  2:25   ` Jeffrey Carter
2003-02-11  8:39   ` Gautier
2003-02-09  2:01 ` Robert A Duff [this message]
2003-02-09  2:33   ` Vinzent Hoefler
2003-02-09  6:07   ` Richard Riehle
2003-02-09  7:13   ` Robert I. Eachus
2003-02-10  4:40     ` Martin Dowie
2003-02-09  2:08 ` Jeffrey Carter
2003-02-10  0:13 ` Leif Holmgren
2003-02-10  9:49 ` Rod Chapman
2003-02-11  9:14 ` Gautier
2003-02-11 13:49   ` Antti Sykari
2003-02-11 17:18   ` Gautier
2003-02-11 17:29     ` Vinzent Hoefler
2003-02-12  1:09   ` Richard Riehle
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox