comp.lang.ada
 help / color / mirror / Atom feed
* ADA Compiling Query
@ 1991-02-11 15:06 Gordon Russell
  1991-02-12 19:01 ` Michael Feldman
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Gordon Russell @ 1991-02-11 15:06 UTC (permalink / raw)



 Hi out there, 
  I am hoping that someone on the network can answer a compiler implementation
problem for me. The problem stems from my PhD research into compiler 
techniques. If we consider the following program extract...


variable1 : integer;

procedure MAIN is
   variable1 : integer;
   result : integer;
----------------------------------------------------
 procedure GET_RESULT(variable2: in out integer) is
  begin
    variable1=2;
    variable2=variable1 + variable2;
  end GET_RESULT;
----------------------------------------------------
 begin
  variable1=10;
  get_result(variable1);
 end MAIN;

My question is.......what is variable1 equal to at the end of MAIN?
There appears to be a number of options....either
   (1) 4
   (2) 12
   (3) Something wierd
   (4) Compiler dependent.

Evidentally, it is reliant on whether GET_RESULT operates on variable2
directly or indirectly. I am hoping that the results are compiler 
dependent. Does anyone have an ADA compiler who is willing to test this?
I am especially interested to hear from official sources (if they are
reading this), since I do not want to break any validation suite
program.

Reply either to this newsgroup or by email. I will post a concensus if
comments are mailed directly to me. Please no flames if this program is
not syntatically correct, as it is the mechanism which I am inquiring 
after. And yes, I do think that this is poor programming practice,
but when has that stopped anyone!

Thanx in advance.....Gordon Russell
                     gor@cs.strath.ac.uk
[I would expect that a look at the standard would answer this question
quickly.  The issue of call by reference vs. call by copy in/copy out is at
least 30 years old.  Algol 60 inadvertently introduced call by name which
forced situations like this to compute the answer 4.  The various Fortran
standards have remained resolutely ambiguous, leaving the interpretation up
to the compiler writer.  The "in out" syntax suggests that copy in/copy out
is expected, but what the syntax suggests and what the standard says are of
course entirely different things. -John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
  1991-02-11 15:06 ADA Compiling Query Gordon Russell
@ 1991-02-12 19:01 ` Michael Feldman
  1991-02-13 21:16 ` Jeff Bartlett
  1991-02-18 14:33 ` ADA Compiling Query stt
  2 siblings, 0 replies; 20+ messages in thread
From: Michael Feldman @ 1991-02-12 19:01 UTC (permalink / raw)


In article <5572@baird.cs.strath.ac.uk> Gordon Russell <gor@cs.strath.ac.uk> writes:
>
>procedure MAIN is
>   variable1 : integer;
>   result : integer;
>----------------------------------------------------
> procedure GET_RESULT(variable2: in out integer) is
>  begin
>    variable1=2;
>    variable2=variable1 + variable2;
>  end GET_RESULT;
>----------------------------------------------------
> begin
>  variable1=10;
>  get_result(variable1);
> end MAIN;

Please don't take this as a flame, Gordon; I'm posting it for others' use as
well. The critique is not of the syntax errors, nor of the fact that this
classical aliasing problem is poor style (which you point out), but the fact
that the answer to this question is readily available in the LRM, namely
sect. 6.2, in which it states quite clearly that this parameter is passed by
copy-in/copy-out. This means that GET_RESULT is working on a local copy of
variable1 (in its alias as variable2). 

For a _scalar_ parameter, the parameter semantics is well-defined. For a
parameter of a _composite_ type, it's not: the implementation can choose
copy-in/copy-out _or_ reference passing. This would have made your question
more interesting.

Here's an exercise I give to my classes, when we discuss this stuff: for some
compiler you have access to, prove that the scalar passing is by value/result
(aka copy-in/copy-out), and write programs to demonstrate the behavior of
passing for composite types. Hint: most compilers use reference passing for
large arrays (common sense, no?); some use value/result for small arrays. If
the latter, find the "crossover".

[This exercise is to create a _purposely_ erroneous program: we _want_ its
behavior to depend on the mechanism :-)]

<WARNING: SERMON COMING>
The LRM is really a good source of information. Serious Ada folks should
have it and use it.
<HERE ENDETH THE SERMON>

Mike Feldman
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
  1991-02-11 15:06 ADA Compiling Query Gordon Russell
  1991-02-12 19:01 ` Michael Feldman
@ 1991-02-13 21:16 ` Jeff Bartlett
  1991-02-14 16:45   ` Michael Feldman
  1991-02-18 14:33 ` ADA Compiling Query stt
  2 siblings, 1 reply; 20+ messages in thread
From: Jeff Bartlett @ 1991-02-13 21:16 UTC (permalink / raw)


In article <5572@baird.cs.strath.ac.uk>, gor@cs.strath.ac.uk (Gordon Russell) writes:
> [ does Ada pass arguments by reference or copy in/copy out?]

See ANSI/MIL-STD-1815A section 6.2 paragraph 7:

    .... The language does not define which of these two mechanisms is to
    be adopted for parameter passing, nor whether different calls to the
    same subprogram are to use the same mechanism.   The execution of a
    program is erroneous if its effect depends on which mechanism is
    selected by the implementation.

And section 1.6 paragraph 6:

    (c) Erroneous execution.

    The language rules specify certain rules to be obeyed by Ada programs,
    although there is no requirement on Ada compilers to provide either a
    compilation-time or run-time detection of the violation of such
    rules. .... The effect of erroneous execution is unpredictable.

Jeff Bartlett
Center for Digital Systems Research
Research Triangle Institute
jb@rti.rti.org       mcnc!rti!jb	(919)-541-6945
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
  1991-02-13 21:16 ` Jeff Bartlett
@ 1991-02-14 16:45   ` Michael Feldman
  1991-02-15 23:09     ` Jim Showalter
  0 siblings, 1 reply; 20+ messages in thread
From: Michael Feldman @ 1991-02-14 16:45 UTC (permalink / raw)


In article <1991Feb13.211643.25777@rti.rti.org> jb@rti.rti.org (Jeff Bartlett) writes:
>In article <5572@baird.cs.strath.ac.uk>, gor@cs.strath.ac.uk (Gordon Russell) writes:
>
>See ANSI/MIL-STD-1815A section 6.2 paragraph 7:
>
>    .... The language does not define which of these two mechanisms is to
>    be adopted for parameter passing, nor whether different calls to the
>    same subprogram are to use the same mechanism.   The execution of a
>    program is erroneous if its effect depends on which mechanism is
>    selected by the implementation.
>
C'mon, guys - a little precision please. This applies only to _structured_
parameters. The preceding paragraph (6) states clearly that _scalars_ are
copied.

I've bumped into a lot of Pascal folks learning Ada who think that passing
an array as IN OUT will magically get it passed by reference. This is a
trick used in Pascal - you pass an array as VAR even if it is being used
as an input parameter, because the _Pascal_ standard requires that it be
copied otherwise. This sticks you in a bind in Pascal, because you've
turned an input parameter into something your procedure may inadvertently
modify. So you've traded speed for reliability. Too bad, but this is
what Prof. Wirth wanted. (It's carried over to Modula-2 also).

Carrying the Pascal trick over to Ada is futile and unnecessary. An IN
parameter _cannot_ be modified; the compiler won't allow it. This permits
the implementer to pass an array (yes, even as an IN parameter) by reference
to save copying time and space. As I said in a previous posting, most
implementers will pass by reference any structure large enough to be of
concern. But if you think that using the Pascal trick - artificially making
the array IN OUT to _guarantee_ that it'll be passed by reference - will
work, guess again.

Mike Feldman

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
  1991-02-14 16:45   ` Michael Feldman
@ 1991-02-15 23:09     ` Jim Showalter
  1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
  0 siblings, 1 reply; 20+ messages in thread
From: Jim Showalter @ 1991-02-15 23:09 UTC (permalink / raw)


There is an unsafe aspect of passing access types as IN parameters in Ada
that is, sad to say, handled rather better in C++.

In Ada, you can pass an access type to a function as an IN:

	type Some_Foo...

        type Pointer is access Some_Foo;

        function Some_Bar (Some_Param : in Pointer)...

And then, inside the function, dereference the pointer and modify the
pointed-to construct.

In C++, you can declare not only the pointer constant but the pointed
to construct constant as well. This allows passing by reference in a
read-only manner, which is NOT possible in Ada at present.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Reference vs. copy semantics in passing parameters
  1991-02-15 23:09     ` Jim Showalter
@ 1991-02-17  0:19       ` Michael Feldman
  1991-02-17 18:54         ` Erland Sommarskog
                           ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Michael Feldman @ 1991-02-17  0:19 UTC (permalink / raw)


In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes:
>There is an unsafe aspect of passing access types as IN parameters in Ada
>that is, sad to say, handled rather better in C++.
>
>In Ada, you can pass an access type to a function as an IN:
>	type Some_Foo...
>        type Pointer is access Some_Foo;
>        function Some_Bar (Some_Param : in Pointer)...
>And then, inside the function, dereference the pointer and modify the
>pointed-to construct.
>
>In C++, you can declare not only the pointer constant but the pointed
>to construct constant as well. This allows passing by reference in a
>read-only manner, which is NOT possible in Ada at present.

Well now I'm curious. Given that only scalars and small structures are
usually passed by copy, why would you want to guarantee reference
passing for read-only parameters in such a kludgy way? Ada provides you
with everything you need:

- parameters large enough to cause performance concerns are passed by
  reference anyway (in any reasonable implementation, anyway);

- IN parameters are read-only, no matter how they are passed.

Am I missing some important other issue here? What aren't you getting
from this combination of features?

Mike Feldman

PS: It seems to me that Ada9x could clarify the issue by simply requiring
that structured parameters be passed by reference (instead of the Ada83
rule that it's implementation-dependent). Since a program whose behavior
depends upon the method of passing is - by definition of the LRM -
erroneous, the only programs that would break would be erroneous ones,
which Ada9x says it doesn't care about. So the clarification would be
upward compatible. Ada9x-ers: what would be the objections?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
@ 1991-02-17 18:54         ` Erland Sommarskog
  1991-02-18 18:41           ` Doug Smith
  1991-02-18  0:36         ` Jim Showalter
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 20+ messages in thread
From: Erland Sommarskog @ 1991-02-17 18:54 UTC (permalink / raw)


Also sprach Micheal Feldman (mfeldman@seas.gwu.edu):
>Jim Showalter (jls@yoda.Rational.COM) writes:
>>In C++, you can declare not only the pointer constant but the pointed
>>to construct constant as well. This allows passing by reference in a
>>read-only manner, which is NOT possible in Ada at present.
>
>Well now I'm curious. Given that only scalars and small structures are
>usually passed by copy, why would you want to guarantee reference
>passing for read-only parameters in such a kludgy way? Ada provides you
>with everything you need:

Don't get confused by terminology. Forget about passing mechanisms.
Remember data abstraction.

If you have a routine which takes a pointer parameter as IN, you
are guaranteed that the *pointer* don't change, but the object
pointed to may be completely altered. For instance look at:

   PROCEDURE P(X : IN ADT);

Am I as a caller that Do_something from this signature guaranteed
that P does not change X? Answer: No. If I look in the package
specification I find that ADT is limited private. Only if I cheat
and sneak into the private part and find that ADT is declared as
a pointer-less type I know that X won't change. If there is a pointer,
and often that's all an ADT is, P may change X just as much as it
wants. Remember that as a user, I may perceive X as a completely
static object.

The practical implication is on the side of the ADT implementor. He
may choose to define ADT as a pointer in order to be able to defer
the record definition to the package body, and thereby reducing
recompilation impact in case he adds or removes a field. The cost
of this is that he loses compiler control of inadvertent changes
to IN parameters, and we're back on the Pascal level.

>PS: It seems to me that Ada9x could clarify the issue by simply requiring
>that structured parameters be passed by reference (instead of the Ada83
>rule that it's implementation-dependent). Since a program whose behavior
>depends upon the method of passing is - by definition of the LRM -
>erroneous, the only programs that would break would be erroneous ones,
>which Ada9x says it doesn't care about. So the clarification would be
>upward compatible. Ada9x-ers: what would be the objections?

Ada should not bind the implementors in order to make ugly
programming unambiguous. Rather I think Ada is going too far
when requiring a certain implementation in some situations.
The IN, OUT and IN OUT modes are a beautiful invention with
exception of the problems mentioned above.
-- 
Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se
"...I cannot understand someone saying 'Rush makes pretty good music, 
but they ARE commercial'." -- William J Bouma

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
  1991-02-17 18:54         ` Erland Sommarskog
@ 1991-02-18  0:36         ` Jim Showalter
  1991-02-18  1:42           ` Michael Feldman
  1991-02-18 18:49           ` Arthur Evans
  1991-02-18 13:10         ` madmats
  1991-05-16 13:51         ` Alex Blakemore
  3 siblings, 2 replies; 20+ messages in thread
From: Jim Showalter @ 1991-02-18  0:36 UTC (permalink / raw)


Yes, but you miss my point (I think?). It is not modification of the
POINTER we are trying to prevent. We are trying to prevent modification
of what the pointer points to, and there is currently no way to insure
this in Ada. A doofus can break the rules with impunity.

Why would it BE a pointer? Beats me, but these things do happen from time
to time, and when they do it would be nice if the language made them safe.

One gross thing that people do currently is give IN/OUT semantics to
parameters on functions by passing a pointer and dereferencing it inside
the function to modify what the pointer points to. There is no way to
prevent this egregious behavior at present (note: many many people have
also requested that 9x include IN/OUT's on functions, which would make
the case for performing the trick just described even weaker).
--
***** DISCLAIMER: The opinions expressed herein are my own. Duh. Like you'd
ever be able to find a company (or, for that matter, very many people) with
opinions like mine. 
                   -- "When I want your opinion, I'll beat it out of you."

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-18  0:36         ` Jim Showalter
@ 1991-02-18  1:42           ` Michael Feldman
  1991-02-18 18:49           ` Arthur Evans
  1 sibling, 0 replies; 20+ messages in thread
From: Michael Feldman @ 1991-02-18  1:42 UTC (permalink / raw)


In article <jls.666837388@yoda> jls@yoda.Rational.COM (Jim Showalter) writes:
>Yes, but you miss my point (I think?). It is not modification of the
>POINTER we are trying to prevent. We are trying to prevent modification
>of what the pointer points to, and there is currently no way to insure
>this in Ada. A doofus can break the rules with impunity.
Hmmm.Are you implying that C++, or whatever, can guarantee that an entire
linked list could be kept safe from modification by making its head pointer
an IN parameter? Neat idea, but how on earth could it be implemented?

If you mean only the directly designated value, i.e. the node (say) that
the pointer points to but not the other nodes "down the line", I don't
really think you've accomplished very much.
>
>Why would it BE a pointer? Beats me, but these things do happen from time
>to time, and when they do it would be nice if the language made them safe.
Well, this is a matter of taste. It's impossible (or nearly, IMHO) to make
the language safe from people who insist on using side effects. The goal,
it seems to me, is to make it difficult to _accidentally_ do stupid things.
If people want to do them deliberately, they will find a way no matter how
safe we think we are building things.
>
>One gross thing that people do currently is give IN/OUT semantics to
>parameters on functions by passing a pointer and dereferencing it inside
>the function to modify what the pointer points to. There is no way to
>prevent this egregious behavior at present (note: many many people have
>also requested that 9x include IN/OUT's on functions, which would make
>the case for performing the trick just described even weaker).
A dumb idea, if you ask me. People are trying to make Ada behave like C.
If they try hard enough to subvert the safety that Ada provides, they will
find a way to succeed. Ada9x is looking at this issue (it's in the
requirements document, but I don't recall if it's a requirement or a study
topic); I hope they leave this as it is in Ada83.

As I recall, the argument for allowing IN/OUT's on functions is that
since nonlocal references are allowed on functions, allowing IN/OUT's  
is a clearer way of doing the same thing. There is a certain logic to
this, I must say. But if you encapsulate the function in a package, using
the nonlocal reference only to maintain state data, with the client unable
to muck with the state variable, then an IN/OUT parameter does _not_
accomplish the same thing, because it exposes the state variable to the client.

Mike Feldman

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
  1991-02-17 18:54         ` Erland Sommarskog
  1991-02-18  0:36         ` Jim Showalter
@ 1991-02-18 13:10         ` madmats
  1991-02-19 19:00           ` Robert I. Eachus
  1991-05-16 13:51         ` Alex Blakemore
  3 siblings, 1 reply; 20+ messages in thread
From: madmats @ 1991-02-18 13:10 UTC (permalink / raw)


In article <2742@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes:
> 
> PS: It seems to me that Ada9x could clarify the issue by simply requiring
> that structured parameters be passed by reference (instead of the Ada83
> rule that it's implementation-dependent). Since a program whose behavior
> depends upon the method of passing is - by definition of the LRM -
> erroneous, the only programs that would break would be erroneous ones,
> which Ada9x says it doesn't care about. So the clarification would be
> upward compatible. Ada9x-ers: what would be the objections?

I think the objections would be that there should be nothing in Ada that
prevents its implementation on a distributed system (without shared
memory). Remote procedure calls and entries cannot reasonably be done
if the reference mechanism is used for parameter passing, even for large
structures.

Mats

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
  1991-02-11 15:06 ADA Compiling Query Gordon Russell
  1991-02-12 19:01 ` Michael Feldman
  1991-02-13 21:16 ` Jeff Bartlett
@ 1991-02-18 14:33 ` stt
  2 siblings, 0 replies; 20+ messages in thread
From: stt @ 1991-02-18 14:33 UTC (permalink / raw)



Re: passing structured parameters by reference

Michael Feldman writes:

> PS: It seems to me that Ada9x could clarify the issue by simply requiring
> that structured parameters be passed by reference (instead of the Ada83
> rule that it's implementation-dependent). Since a program whose behavior
> depends upon the method of passing is - by definition of the LRM -
> erroneous, the only programs that would break would be erroneous ones,
> which Ada9x says it doesn't care about. So the clarification would be
> upward compatible. Ada9x-ers: what would be the objections?

Here are some important reasons for allowing by-copy parameter passing:

1) It supports parameter passing between parts of a distributed
program which don't share memory.

2) It allows a slice of a packed array to be copied into an aligned
temporary, rather than forcing every subprogram to handle a descriptor
for an unaligned parameter.

3) It allows very short arrays/records to be passed in registers
(e.g. a packed array of 16 booleans).

4) It is necessary when the actual parameter is in the form of a type
conversion, and the target and source type don't have the same
representation (e.g. one is packed and the other isn't).

S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA  02138

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-17 18:54         ` Erland Sommarskog
@ 1991-02-18 18:41           ` Doug Smith
  0 siblings, 0 replies; 20+ messages in thread
From: Doug Smith @ 1991-02-18 18:41 UTC (permalink / raw)


In article <2635@enea.se> sommar@enea.se (Erland Sommarskog) writes:
> Also sprach Micheal Feldman (mfeldman@seas.gwu.edu):
> >Jim Showalter (jls@yoda.Rational.COM) writes:
> >>In C++, you can declare not only the pointer constant but the pointed
> >>to construct constant as well. This allows passing by reference in a
> >>read-only manner, which is NOT possible in Ada at present.
> >
> >Well now I'm curious. Given that only scalars and small structures are
> >usually passed by copy, why would you want to guarantee reference
> >passing for read-only parameters in such a kludgy way? Ada provides you
> >with everything you need:
> 
> Don't get confused by terminology. Forget about passing mechanisms.
> Remember data abstraction.
> 
More specifically, notice how an ADT can be specified to control the
ambiguity of parameter modes for pointers to complex data structures.
Although a particular implementation of linked list might always
initialize a header record, then never need to change it during
Prepends, Appends, etc., IN OUT can enforce the intent of the
operations.  For example:

    package Linked_Integer_Operations is
        type Lists is limited private;

        procedure Append (List    : in out Lists;
                          Element : in     Integer);

    private
        ... Declare Lists as an initialized record whose value
            doesn't have to change during the Append operation.
    end;

Now the application engineer cannot accidently change a list that he
did not originally intend to change:

    procedure Reorder_List (New_List : in out Lists;
                            Old_List : in     Lists) is
    begin
        Append (Old_List, 0); -- will not compile !!!
    end;

    --    RM 6.4.1(3): actual must be a variable name or a conversion
    --    RM 6.2(3): assignment to an IN parameter not allowed

No matter how arrogant I become about my own programming skills, this
kind of compile time checking has saved me many headaches!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-18  0:36         ` Jim Showalter
  1991-02-18  1:42           ` Michael Feldman
@ 1991-02-18 18:49           ` Arthur Evans
  1991-02-19  2:05             ` Michael Feldman
  1 sibling, 1 reply; 20+ messages in thread
From: Arthur Evans @ 1991-02-18 18:49 UTC (permalink / raw)
  Cc: jls

Jim Showalter (jls@yoda.Rational.COM) comments that Ada 9X might permit
functions to have parameters of mode IN OUT or OUT.

An early draft of the Requirements Document included a requirement for
such a change.  However, because of many comments opposing the change it
was removed from the final document.

Art Evans

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-18 18:49           ` Arthur Evans
@ 1991-02-19  2:05             ` Michael Feldman
  0 siblings, 0 replies; 20+ messages in thread
From: Michael Feldman @ 1991-02-19  2:05 UTC (permalink / raw)


In article <16152@as0c.sei.cmu.edu> ae@sei.cmu.edu (Arthur Evans) writes:
>Jim Showalter (jls@yoda.Rational.COM) comments that Ada 9X might permit
>functions to have parameters of mode IN OUT or OUT.
>
>An early draft of the Requirements Document included a requirement for
>such a change.  However, because of many comments opposing the change it
>was removed from the final document.

A good decision, IMHO. A function should be as nearly a "black box" as
possible, which has no side effects. In Ada a function that has state
memory (a pseudo-random number generator, for example), must have a side
effect (of modifying a variable of the package body it's in, presumably).
This could have been prevented if Ada had allowed _static_ data structures
in subprograms, a la PL/1, C, and Fortran. But alas, it doesn't, and I'm
sure it won't.

But in any case, the client of the function should not be able to cause
side effects. Just because other languages have "value-returning procedures"
or "functions with side effects" (dpending on how you want to look at it)
doesn't mean Ada needs to. Let functions be functions.

Mike Feldman

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-18 13:10         ` madmats
@ 1991-02-19 19:00           ` Robert I. Eachus
  0 siblings, 0 replies; 20+ messages in thread
From: Robert I. Eachus @ 1991-02-19 19:00 UTC (permalink / raw)



In article <2742@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes:
   > 
   > PS: It seems to me that Ada9x could clarify the issue by simply requiring
   > that structured parameters be passed by reference (instead of the Ada83
   > rule that it's implementation-dependent). Since a program whose behavior
   > depends upon the method of passing is - by definition of the LRM -
   > erroneous, the only programs that would break would be erroneous ones,
   > which Ada9x says it doesn't care about. So the clarification would be
   > upward compatible. Ada9x-ers: what would be the objections?

   There are two other reasons for allowing arrays to be passed by
copy: descriptors and slices.  For example, if I pass a STRING to a
Text_IO routine, it will almost certainly require a descriptor be
passed also. However, if I declare a constrained sting type:

  type MyString is array (Integer range 1..10) of Standard.Character;

Then no descriptor is required to call:

  procedure FOO(S: in MyString);

So far so good, but now let us declare a record type with no room for
descriptors: 

  type MyRec is record S: String(1...10); end record;
  for MyRec'SIZE use 80;
  MR: MyRec := (S => "Try this..");

Now we call Text_IO.Put_Line(MR).  Where does the descriptor come
from?  The easy solution is to make this call by copy, and generate
a descriptor for the area copied to.  A similar problem occurs if an
array is packed as part of a record--unpacking produces a copy.

As for slices try:

   type Bit_Array is array (Integer range <>) of Boolean;
   pragma PACK(Bit_Array);
   X: Bit_Array(1..1000) := (others => FALSE);
   
Now how do you handle X(2..11) := X(30..39) and X(100..109); ?
Most compilers will copy the slices so that the copies begin on byte
or word boundaries rather than impose the overhead of bit level
pointers on all subprograms which have parameters of such types. (This
way you only incur the cost when you use such a feature, and in the
above example  the generated code will probably be much more efficient
in the pass by copy case.

   Notice that in both cases the decision as to whether to pass by
copy or by reference is made when the call is compiled not when the
subprogam itself is compiled.  This is the reason for the standard
warning that the compiler is allowed to change the parameter passing
mechanism from call to call, and even from one invocation to the next.
For example, in the bit slice example, if you have:

     X(A..B) := X(C..D) and X(E..F);

the generated code might call a run-time routine which will makes a
copy only when A, C or E is not a multiple of eight, so on a
particular call one parameter might be passed by copy and the other by
reference.
--

					Robert I. Eachus

     Our troops will have the best possible support in the entire
world.  And they will not be asked to fight with one hand tied behind
their back.  President George Bush, January 16, 1991

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ADA Compiling Query
       [not found] <5572@baird.cs.strath.ac.uk#  <20600085@inmet>
@ 1991-02-21 20:40 ` Michael Feldman
  0 siblings, 0 replies; 20+ messages in thread
From: Michael Feldman @ 1991-02-21 20:40 UTC (permalink / raw)


In article <20600085@inmet#  stt@inmet.inmet.com writes:
# 
# Here are some important reasons for allowing by-copy parameter passing:
# 
# 1) It supports parameter passing between parts of a distributed
# program which don't share memory.
# 
# 2) It allows a slice of a packed array to be copied into an aligned
# temporary, rather than forcing every subprogram to handle a descriptor
# for an unaligned parameter.
# 
# 3) It allows very short arrays/records to be passed in registers
# (e.g. a packed array of 16 booleans).
# 
# 4) It is necessary when the actual parameter is in the form of a type
# conversion, and the target and source type don't have the same
# representation (e.g. one is packed and the other isn't).
# 
# S. Tucker Taft
# Intermetrics, Inc.
# Cambridge, MA  02138

I think we've come to the end of this thread. I think I started this one,
and I've read a lot of interesting network traffic on it, including some
nice private notes. I think Tucker has encapsulated the issues very well,
and I just want to thank him publicly for another enlightening summary
of an interesting language issue. Thanks!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
                           ` (2 preceding siblings ...)
  1991-02-18 13:10         ` madmats
@ 1991-05-16 13:51         ` Alex Blakemore
  1991-05-17  8:19           ` Matthias Ulrich Neeracher
                             ` (2 more replies)
  3 siblings, 3 replies; 20+ messages in thread
From: Alex Blakemore @ 1991-05-16 13:51 UTC (permalink / raw)


In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes:
> In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes:
> In C++, you can declare not only the pointer constant but the pointed
> to construct constant as well. This allows passing by reference in a
> read-only manner, which is NOT possible in Ada at present.

This sounds like a nice safety feature but can callers really rely on it ?
Even if the C++ language prevents updating the object if the pointer is
declared appropriately, does it prevent assignment to a normal pointer
which will allow the referenced object to be updated ?

I know very little about C++, but will attempt to pose an argument
against this feature in Ada terms.  Perhaps someone with C++ knowledge
could explain why this feature is really desirable ?

Consider this Ada flavored example, where constant means the referenced
object may not be updated.

procedure look_at_object (p : in CONSTANT ptr_to_object);

procedure look_at_object (p : in CONSTANT ptr_to_object) is
  temp : ptr_to_object;
begin 
  temp := p;  -- is this legal in C++ ?
  p.all := anything;
end;

Unless C++ prevents the assignment to another pointer above, then the feature
can be easily subverted (purposely or accidently).  that means callers have to
  a. trust that the body really obeys the implication in the parameter mode to not
     update the referenced object 
or
  b. examine the body to make sure.

  Since the new mode cannot be really trusted (as defined above),
it doesnt really aid in reasoning about a program's behavior.
It can prevent some simple errors that are relatively easy to spot 
(e.g. p.anything on lhs of assignemnt) but can't prevent the more
tricky types of errors.  It can even do harm by giving a false sense of assurance.

 Of course this argument falls apart if you invent more rules to prevent
making copies of such pointers in anyway, but can you do that without
making the language even more complex?  Besides the assignment you'ld have to
make sure parameters of such modes could only be passed by the same mode
to other subprograms.
-- 
---------------------------------------------------------------------
Alex Blakemore           blakemore@software.org        (703) 742-7125
Software Productivity Consortium  2214 Rock Hill Rd, Herndon VA 22070

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-05-16 13:51         ` Alex Blakemore
@ 1991-05-17  8:19           ` Matthias Ulrich Neeracher
  1991-05-17 13:44           ` Markku Sakkinen
  1991-05-28  5:28           ` Kenneth Almquist
  2 siblings, 0 replies; 20+ messages in thread
From: Matthias Ulrich Neeracher @ 1991-05-17  8:19 UTC (permalink / raw)


In article <1991May16.135103.1688@software.org> blakemor@software.org (Alex Blakemore) writes:
>In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes:
>> In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes:
>> In C++, you can declare not only the pointer constant but the pointed
>> to construct constant as well. This allows passing by reference in a
>> read-only manner, which is NOT possible in Ada at present.
>
>This sounds like a nice safety feature but can callers really rely on it ?
>Even if the C++ language prevents updating the object if the pointer is
>declared appropriately, does it prevent assignment to a normal pointer
>which will allow the referenced object to be updated ?
>[...]
>Consider this Ada flavored example, where constant means the referenced
>object may not be updated.
>
>procedure look_at_object (p : in CONSTANT ptr_to_object);
>
>procedure look_at_object (p : in CONSTANT ptr_to_object) is
>  temp : ptr_to_object;
>begin 
>  temp := p;  -- is this legal in C++ ?
>  p.all := anything;
>end;
>
>Unless C++ prevents the assignment to another pointer above, then the feature
>can be easily subverted (purposely or accidently).

[Sorry to post C++ to comp.lang.ada, but the question is posted here]

In C++, the above assignment is illegal, so the risk of subverting the feature
accidentally is low. On the other hand, the assignment can easily be done if an
explicit type cast to the non-constant type is employed in the right-hand side,
so the feature can indeed easily be subverted purposely.

I tend to agree with this design philosophy, as I believe that it is beneficial
to try to guard programmers from their own stupid... I mean fallibility, but that
there is little use of trying to control their malice with programming language
features. A borderline case is, of course, programmer's lazyness.

Matthias

-----
Matthias Neeracher                                      neeri@iis.ethz.ch
   "These days, though, you have to be pretty technical before you can 
    even aspire to crudeness." -- William Gibson, _Johnny Mnemonic_

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-05-16 13:51         ` Alex Blakemore
  1991-05-17  8:19           ` Matthias Ulrich Neeracher
@ 1991-05-17 13:44           ` Markku Sakkinen
  1991-05-28  5:28           ` Kenneth Almquist
  2 siblings, 0 replies; 20+ messages in thread
From: Markku Sakkinen @ 1991-05-17 13:44 UTC (permalink / raw)


In article <1991May16.135103.1688@software.org> blakemor@software.org (Alex Blakemore) writes:
>In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes:
>> In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes:
>> In C++, you can declare not only the pointer constant but the pointed
>> to construct constant as well. This allows passing by reference in a
>> read-only manner, which is NOT possible in Ada at present.

I think the original poster has erred here: nothing prevents an Ada
implementation from passing 'in' parameters by reference whenever that
is most convenient or efficient.  (I think Ada's 'in' parameters are
a significant improvement over the value parameters of Algol and Pascal.)
However, the 'pointer to constant' feature of C++ may be
worth discussing in this newsgroup, because its applicability is _not_
restricted to parameter passing.

The meaning of 'const' in C++ should be noted.  If Ada had the same approach
to constants, we could have something like:
   type object;
   type immutable is constant object;
   type ptr_to_object is access object;
   type ptr_to_immutable is access immutable;
An 'immutable' value could be directly assigned to an 'object' variable,
and a 'ptr_to_object' value to a 'ptr_to_immutable' variable.
Thus, types like 'ptr_to_immutable' are, strictly speaking, not
"pointer to constant" types, but rather "non-modifying pointer" types:
the object pointed to may well be modified, but not via this reference.

>This sounds like a nice safety feature but can callers really rely on it ?
>Even if the C++ language prevents updating the object if the pointer is
>declared appropriately, does it prevent assignment to a normal pointer
>which will allow the referenced object to be updated ?

Of course, you cannot _really_ rely on anything in a C-based language:
by fooling around with pointers you can even overwrite _code_ unless
the operating systems protects code segments.  Such things are "illegal"
in principle, although it is difficult to imagine a C or C++ implementation
that could catch them.  --  But indeed, the kind of assignment (or cast)
that you asked about is fully _legal_ C++ according to the most
authoritative definition!

>I know very little about C++, but will attempt to pose an argument
>against this feature in Ada terms.  Perhaps someone with C++ knowledge
>could explain why this feature is really desirable ?
>
>Consider this Ada flavored example, where constant means the referenced
>object may not be updated.
> ...
>procedure look_at_object (p : in CONSTANT ptr_to_object) is
>  temp : ptr_to_object;
>begin 
>  temp := p;  -- is this legal in C++ ?
                  ^^^^^^^^^
>  p.all := anything;
>end;

An assignment corresponding to the above is _not_ legal in C++,
the legal case would correspond ("Adaified") to:
   temp := ptr_to_object (p);
Using my previous type declarations, the procedure header would be:
   procedure look_at_object (p : in ptr_to_immutable)

Actually, this whole example is not very convincing of the need
for such pointer types.
If we take the above C++-like meaning of "non-modifying pointer",
the procedure could just as well be declared as
   procedure look_at_object (o : in object)
If we would like a true "pointer to constant" meaning, then:
   procedure look_at_object (i : in immutable)

>Unless C++ prevents the assignment to another pointer above, then the feature
>can be easily subverted (purposely or accidently).  [...]

Yes, but I think that the feature combined with some programming discipline
is nevertheless useful.  Of course, if this feature were to be
introduced in Ada (or some other language with stronger typing than C++),
one would probably not allow such dangerous conversions.
(They fit the general spirit of C and C++, but not the spirit of Ada.)

> ...
> Of course this argument falls apart if you invent more rules to prevent
>making copies of such pointers in anyway, but can you do that without
>making the language even more complex?  Besides the assignment you'ld have to
>make sure parameters of such modes could only be passed by the same mode
>to other subprograms.

Since "pointer to constant something" is regarded as a distinct type
and not as a specific device for parameter passing, I don't think it
would cause any "cascading" complexity;  existing type rules would
be quite sufficient.

Markku Sakkinen
Department of Computer Science and Information Systems
University of Jyvaskyla (a's with umlauts)
PL 35
SF-40351 Jyvaskyla (umlauts again)
Finland
          SAKKINEN@FINJYU.bitnet (alternative network address)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Reference vs. copy semantics in passing parameters
  1991-05-16 13:51         ` Alex Blakemore
  1991-05-17  8:19           ` Matthias Ulrich Neeracher
  1991-05-17 13:44           ` Markku Sakkinen
@ 1991-05-28  5:28           ` Kenneth Almquist
  2 siblings, 0 replies; 20+ messages in thread
From: Kenneth Almquist @ 1991-05-28  5:28 UTC (permalink / raw)


>In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes:
>> In C++, you can declare not only the pointer constant but the pointed
>> to construct constant as well. This allows passing by reference in a
>> read-only manner, which is NOT possible in Ada at present.

This feature has also been included in the ANSI C standard.

blakemor@software.org (Alex Blakemore) asks:
> This sounds like a nice safety feature but can callers really rely on it ?
> Even if the C++ language prevents updating the object if the pointer is
> declared appropriately, does it prevent assignment to a normal pointer
> which will allow the referenced object to be updated ?

The "constant" attribute is part of the type, so the type checking system
makes this secure *unless* the type system is circumvented by the use of
a type cast.  (By "type cast", I mean the C equivalent of Ada's
UNCHECKED_CONVERSION.)  The rule is that a pointer to a non-constant
object can be assigned to a pointer to a constant object, but not the
other way around.  (Assignment includes parameter passing.)

A problem with the "constant" attribute is that it is not inherited
properly.  Consider a routine that looks up an entry in a data
structure like a tree or a string, and returns a pointer to the
element found.  The returned pointer should point to a constant object
iff the data structure was declared to be constant, but the C type
system doesn't handle this.  For this reason, several routines in the
standard ANSI C library are defined in such a way that they cannot be
implemented without using type casts.
					Kenneth Almquist

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~1991-05-28  5:28 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1991-02-11 15:06 ADA Compiling Query Gordon Russell
1991-02-12 19:01 ` Michael Feldman
1991-02-13 21:16 ` Jeff Bartlett
1991-02-14 16:45   ` Michael Feldman
1991-02-15 23:09     ` Jim Showalter
1991-02-17  0:19       ` Reference vs. copy semantics in passing parameters Michael Feldman
1991-02-17 18:54         ` Erland Sommarskog
1991-02-18 18:41           ` Doug Smith
1991-02-18  0:36         ` Jim Showalter
1991-02-18  1:42           ` Michael Feldman
1991-02-18 18:49           ` Arthur Evans
1991-02-19  2:05             ` Michael Feldman
1991-02-18 13:10         ` madmats
1991-02-19 19:00           ` Robert I. Eachus
1991-05-16 13:51         ` Alex Blakemore
1991-05-17  8:19           ` Matthias Ulrich Neeracher
1991-05-17 13:44           ` Markku Sakkinen
1991-05-28  5:28           ` Kenneth Almquist
1991-02-18 14:33 ` ADA Compiling Query stt
     [not found] <5572@baird.cs.strath.ac.uk#  <20600085@inmet>
1991-02-21 20:40 ` Michael Feldman

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