From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,13b19740d69cbdc2 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-10 12:06:54 PST Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newshub.sdsu.edu!elnk-nf2-pas!newsfeed.earthlink.net!stamper.news.pas.earthlink.net!newsread4.news.pas.earthlink.net.POSTED!not-for-mail From: Jeffrey Carter Organization: jrcarter commercial-at acm [period | full stop] org User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.4) Gecko/20030624 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Modes (was unbounded_string) References: <20031010074015.761204C40C1@lovelace.ada-france.org> In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: Date: Fri, 10 Oct 2003 19:06:00 GMT NNTP-Posting-Host: 63.184.8.118 X-Complaints-To: abuse@earthlink.net X-Trace: newsread4.news.pas.earthlink.net 1065812760 63.184.8.118 (Fri, 10 Oct 2003 12:06:00 PDT) NNTP-Posting-Date: Fri, 10 Oct 2003 12:06:00 PDT Xref: archiver1.google.com comp.lang.ada:642 Date: 2003-10-10T19:06:00+00:00 List-Id: Andrew Carroll wrote: >>>For all other types, the compiler chooses the parameter >>>mode best suited to the type. If I wrote that, then I made an error. It should be, "the compiler chooses the parameter passing mechanism best suited to the type." > package x is > type x; > type xptr is access x; > type x is tagged limited record > head: nodeptr; > something: unbounded_string; > end record; > > --creates a new node to put into the 'head' list. > --new node is created from information in token. > --token has nothing to do with the 'something' variable > --declared in the record above. > procedure add(this: xptr; token: unbounded_string); > > end x; > > So, with the above code "example", xptr is passed as an 'in' > or 'in out' mode at the add procedure? Since you didn't specify the mode, the mode is "in". That has nothing to do with the parameter passing mechanism. > Are you saying that I should use just x and not xptr as the > parameter so that the compiler will choose the correct mode? Since you seem to be dealing with a dynamically allocated structure, then pointers are probably fine for implementing the structure. But there seems to no need for the client to pass in a value of type X or Xptr. There is even no need for the client to know about the details of these types. Instead, you should have a Head_List type which is [limited] private; the client should pass in an object of type Head_List (mode in out, so it can be modified), and a value of type Unbounded_String to add to the Head_List. Add allocates a new node and links it into the list. Head_List should probably be controlled so you can manage its memory. > If so, you recommend it because of deallocation issues? Precisely. With the pointer type exposed, and the client required to use it, the client becomes responsible for memory management and it has to be scattered all over the client's code. It's practically impossible to avoid errors that way. With the implementation hidden, all the memory management is in one place. Getting it right is easier; finding and fixing errors is easier. The client's code is simpler. > Is there something in the code below that I missed about information > hiding? > > Temp: gnat.os_lib.String_Access; > ... > Temp := gnat.os_lib.getenv("QUERY_STRING"); > ... > --------------------------------------- > -- ready to use Temp for something else > --------------------------------------- > Temp := gnat.os_lib.getenv("SOME_OTHER_VARIABLE"); Since GNAT.OS_Lib.Getenv returns type String_Access, you have to use String_Access if you want to use Getenv. But note the description of Getenv from GNAT.OS_Lib: -- Get the value of the environment variable. Returns an access -- to the empty string if the environment variable does not exist -- or has an explicit null value (in some operating systems these -- are distinct cases, in others they are not; this interface -- abstracts away that difference. The argument is allocated on -- the heap (even in the null case), and needs to be freed explicitly -- when no longer needed to avoid memory leaks. Your code leaks memory, because the package has dumped the memory management onto the client, and you haven't done it. This is not, in my opinion, a good way to do this. Getenv should return a string, and deal with any memory management issues. Note that Kazakov's versions using Unbounded_String and renaming the string pointed to also leak memory. > Considering the code above, what is the "Ada idiom" to "resize" a String > without pointers and dynamic allocation? In other words; what "Ada > idiom" code would you write to do the same thing I did, without pointers > and dynamic allocation? You don't have to write the code, a good > reading reference would be okay. If you have to use GNAT.OS_Lib.Getenv, I would do something like declare Temp : String_Access := Getenv; Env : constant String := Temp.all; begin Free (Temp); -- Deal with Env end; If you're speaking in general about having a string object that can hold values of different lengths, then you want to use Ada.Strings.[Un]Bounded. Something : Unbounded_String; function Get return String is ...; ... Something := To_Unbounded_String (Get); ... -- Repeat as desired Very often in Ada, though, you can create [constant] Strings as you go, eliminating the need for [Un]Bounded_String. -- Jeff Carter "C++ is like jamming a helicopter inside a Miata and expecting some sort of improvement." Drew Olbrich 51