From: andrewd@cs.adelaide.edu.au (Andrew Dunstan)
Newsgroups: comp.lang.ada
Subject: Re: ADA question
Date: 29 Aug 92 00:37:01 GMT

In article <1992Aug27.102951.8681@news.uni-stuttgart.de>, ucaa2385@ruscvx.rus.uni-stuttgart.de (Peter Hermann) writes:
|> In article <1992Aug27.004228.19551@evb.com> jjh@evb.com (John Halper) writes:
|> >Daljeet writes:
|> >>I have a function in a package A which returns string. I am using
|> >>that function in another package B and try to give the value returned
|> >>by that function to a variable (which has been declared in package B).
|> >>The variable is of type string (1 .. max) initialised to empty string.
|> >
|> >I don't like making the call twice, and would rather use one of first two 
|> >solutions, but ...
|> 
|> It is advisable to call any function only once
|> for the same purpose, because a function result
|>  1. may change from call to call
|>  2. may be expensive
|>

Absolutely! Avoid this like the plague.
 
|> If and only if you have enough space or your strings
|> to be processed are small enough, respectively,
|> then you may code the following:
|> 
|> DECLARE
|>    String_Const : CONSTANT String := My_String_Function;
|>    String_Var : String (String_Const'RANGE) := String_Const ;
|> BEGIN
|>    Process (String_Var) ; -- parameter's mode: IN OUT
|> END ;
|> 
|> An advanced compiler may possibly sweat out the extra space
|> for the constant. Perhaps all compilers of the next generation
|> are apt enough?
|>

This is based on my original suggestion, but copies the string into a
variable, which has to be done since "process" is now specified to
take an in out parameter. Unfortunately, this involves the cost of copying
the string, and if the code is called many times this cost can be substantial.
Remember that we really wanted a string variable in the first place, and
only used a constant because it meant we could decalre it without explicit
constraints. To avoid the cost of copying, you could try this, although it
won't necessarily work on all compilers:

 DECLARE
    String_Const : CONSTANT String := My_String_Function;
    String_Var : String (String_Const'RANGE) ;
    for string_var use at string_const'address ;
 BEGIN
    Process (String_Var) ; -- parameter's mode: IN OUT
 END ;
 
Now there is no copying, and no extra storage allocation. It's a bit gross,
but it should work.

|> After all, I hope that Ada9x relaxes the situation anyway,
|> in that a declaration like
|>    String_Var : String := My_String_Function;
|> will become valid. This would create a constrained array
|> by inspection of the initialization value.

It will. Both arrays and discriminated records will be able to be declared
of an unconstrained type and take on constraints from the initialising
expression. In fact, while 9X is far from perfect it promises so many
good things like this that I am getting really impatient to see it.

-- 
#######################################################################
#  Andrew Dunstan                   #   There's nothing good or bad   #
#  Department of Computer Science   #   but thinking makes it so.     #
#  University of Adelaide           #                                 #
#  South Australia                  #          - Shakespeare          #
#  net: andrewd@cs.adelaide.edu.au  #                                 #
#######################################################################
Newsgroups: comp.lang.ada