comp.lang.ada
 help / color / mirror / Atom feed
* Modes (was unbounded_string)
       [not found] <20031010074015.761204C40C1@lovelace.ada-france.org>
@ 2003-10-10  8:27 ` Andrew Carroll
  2003-10-10  9:15   ` Dmitry A. Kazakov
                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Andrew Carroll @ 2003-10-10  8:27 UTC (permalink / raw)
  To: comp.lang.ada

>>For all other types, the compiler chooses the parameter 
>>mode best suited to the type. 
Great!!!  SIGN ME UP!!!  But...is it possible that the compiler 
doesn't get it right?  What would I need to do if I found that
the compiler didn't get it right in my testing?  I'm guessing
that you will say, "specify the mode".

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?  

Are you saying that I should use just x and not xptr as the
parameter so that the compiler will choose the correct mode?
If so, you recommend it because of deallocation issues?


On to strings...
>> Basically, you have reinvented the wheel. What you have is 
>> Unbounded_String, but with its guts hanging out all over the place, 
>> instead of using information hiding as a software engineer should, and 
>> as Ada.Strings.Unbounded does.
[snip]
>> The "Ada Way" / "Ada idiom"

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");

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.

Thanks!
















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

* Re: Modes (was unbounded_string)
  2003-10-10  8:27 ` Modes (was unbounded_string) Andrew Carroll
@ 2003-10-10  9:15   ` Dmitry A. Kazakov
  2003-10-11  7:16     ` Simon Wright
  2003-10-10 15:18   ` Stephen Leake
  2003-10-10 19:06   ` Jeffrey Carter
  2 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2003-10-10  9:15 UTC (permalink / raw)


On Fri, 10 Oct 2003 02:27:19 -0600, "Andrew Carroll"
<andrew@carroll-tech.net> wrote:

>>>For all other types, the compiler chooses the parameter 
>>>mode best suited to the type. 
>Great!!!  SIGN ME UP!!!  But...is it possible that the compiler 
>doesn't get it right?  What would I need to do if I found that
>the compiler didn't get it right in my testing?  I'm guessing
>that you will say, "specify the mode".

You cannot directly specify the by-value vs. by-reference mode.

>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?  

It depends only on whether the value of the pointer This has to be
modified by Add. If yes, then the mode is "in out". If not, then the
mode is "in". If it is a garbage and has to be set in Add, then the
mode has to be "out". Note that all this has nothing to do with the
object the value of This points to. It is This, an access type object,
which is passed to Add, not the object which it accidentally points
(or not) to.

>Are you saying that I should use just x and not xptr as the
>parameter so that the compiler will choose the correct mode?

The rule of thumb is: newer use pointers if there is an alternative.
So:

   procedure Add (This: in out X; Token: Unbounded_String); 

Note that X is tagged limited, so it will be passed by reference as
expected. There is nothing to choose for the compiler. Observe also
subtle pitfalls caused by pointers: your Add is not a primitive
subprogram of X. So it cannot be overridden by descendant types! Thus
another rule: if a pointer, then when possible anonymous:

   procedure Add (This: access X; Token: Unbounded_String); 
      -- This will be a primitive subprogram of X

>If so, you recommend it because of deallocation issues?

Irrelevant. In 90% cases, just forget that there is any difference
between by-reference vs. by-value.

>On to strings...
>>> Basically, you have reinvented the wheel. What you have is 
>>> Unbounded_String, but with its guts hanging out all over the place, 
>>> instead of using information hiding as a software engineer should, and 
>>> as Ada.Strings.Unbounded does.
>[snip]
>>> The "Ada Way" / "Ada idiom"
>
>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");
>
>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.

with Ada.Strings.Unbounded;  use Ada.Strings.Unbounded;
with GNAT.OS_Lib; use GNAT.OS_Lib;
...
Temp : Unbounded_String;
...
Temp := To_Unbounded_String (Getenv ("QUERY_STRING").all);
   -- Note that Temp is a copy of the env-string. So you can
   -- modify it.
...
Temp := To_Unbounded_String (Getenv ("SOME_OTHER_VARIABLE").all);

BUT FORGET IT AT ONCE! The Ada way is not to create objects you do not
need. The right way:

with GNAT.OS_Lib; use GNAT.OS_Lib;
...
declare  -- I need the value of QUERY_STRING here
   Temp : String renames Getenv ("QUERY_STRING").all;
      -- Temp is an alias to the env-string. You cannot modify it.
      -- Yet it is not a pointer. An analogue would be C++ reference
begin
   ... -- Doing with Temp everything I can to do to
       -- a constant String
end; -- I don't need it anymore

for example:

function Query_Variable_Name return String is ...;
--
-- Print all queried env-strings, which values start with 'A':
--
loop
   declare
      Name : constant String := Query_Variable_Name;
   begin
      exit when Name'Length = 0;
      declare
         Value : String renames Getenv (Name).all;
      begin
         if Value'Length > 0 and then Value (Value'First) = 'A' then
            Put_Line (Name & "=" & Value);
         end if;
      end;
   end;
end loop;

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Modes (was unbounded_string)
       [not found] <20031010094017.680474C40C1@lovelace.ada-france.org>
@ 2003-10-10 10:58 ` Andrew Carroll
  0 siblings, 0 replies; 15+ messages in thread
From: Andrew Carroll @ 2003-10-10 10:58 UTC (permalink / raw)
  To: comp.lang.ada


> Message: 7
> Date: Fri, 10 Oct 2003 11:15:27 +0200
> From: Dmitry A. Kazakov <mailbox@dmitry-kazakov.de>
> Subject: Re: Modes (was unbounded_string)
> To: comp.lang.ada@ada-france.org
> Message-ID: <htqcov8rj5v1ii4aiad48sso0dhj0glcan@4ax.com>
> Content-Type: text/plain; charset=us-ascii
> 
> On Fri, 10 Oct 2003 02:27:19 -0600, "Andrew Carroll"
> <andrew@carroll-tech.net> wrote:
> 
[snip]
> The rule of thumb is: newer use pointers if there is an alternative.
> So:
[snip]
>Thus another rule: if a pointer, then when possible anonymous:
>    procedure Add (This: access X; Token: Unbounded_String); 
>       -- This will be a primitive subprogram of X
> 
[snip]
> The Ada way is not to create objects you do not need.

Okay, so now we're getting to the information I want to know.
The "rules of thumb" for the "Ada idiom".  Anyone got a list of 
"standardized rules of thumb for the Ada idiom"?








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

* Re: Modes (was unbounded_string)
  2003-10-10  8:27 ` Modes (was unbounded_string) Andrew Carroll
  2003-10-10  9:15   ` Dmitry A. Kazakov
@ 2003-10-10 15:18   ` Stephen Leake
  2003-10-10 16:21     ` Martin Dowie
  2003-10-14 18:47     ` Craig Carey
  2003-10-10 19:06   ` Jeffrey Carter
  2 siblings, 2 replies; 15+ messages in thread
From: Stephen Leake @ 2003-10-10 15:18 UTC (permalink / raw)


"Andrew Carroll" <andrew@carroll-tech.net> writes:

> >>For all other types, the compiler chooses the parameter 
> >>mode best suited to the type. 
> Great!!!  SIGN ME UP!!!  But...is it possible that the compiler 
> doesn't get it right?  

What does "right" mean here? Part of the point is that most of the
time it does not matter whether things are passed by copy or
reference. If you right code where it does matter, that code is
erroneous. Note that the same code would be erroneous in any other
language.

Tagged types and full limited types are always passed by reference,
because it almost always matters for them.

> What would I need to do if I found that the compiler didn't get it
> right in my testing? I'm guessing that you will say, "specify the
> mode".

You can't specify the parameter passing mechanism, except by making
the type tagged or fully limited.

> 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?  

Ah. You are confused. Let me back up.

If you do not specify "in" or "in out", the mode is "in". 

But that is _not_ what we meant by "let the compiler choose". We were
talking about "by reference" vs "by copy". 

"in" does _not_ mean "by copy". It just means "a constant view; you
can't assign to it". It may be passed by copy or by reference.
Similarly, "in out" does _not_ mean "by reference"; it just means "a
variable view; you can assign to it". It my also be passed by copy;
the compiler writes the local copy back to the calling copy on
subprogram return.

> Are you saying that I should use just x and not xptr as the
> parameter so that the compiler will choose the correct mode? 

Almost. You should use X, but specify "in" or "in out". The compiler
will decide whether to pass by reference or by copy.

> If so, you recommend it because of deallocation issues?

Yes. And general clarity; using pointers usually means you are doing
dynamic memory allocation, and/or dynamic dispatching. If you are not,
don't use pointers.

> 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 you are using environment variables, this is the correct idiom;
environment variables are not an Ada thing, you have to use whatever
the compiler provides.

> Considering the code above, what is the "Ada idiom" to "resize" a String
> without pointers and dynamic allocation?  

Note that you did _not_ "resize" anything. gnat.os_lib.getenv returns
a pointer to a string, not a string. On the second call, you get
another pointer. Both environment strings are still there, unmodified.

-- 
-- Stephe



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

* Re: Modes (was unbounded_string)
  2003-10-10 15:18   ` Stephen Leake
@ 2003-10-10 16:21     ` Martin Dowie
  2003-10-14 18:47     ` Craig Carey
  1 sibling, 0 replies; 15+ messages in thread
From: Martin Dowie @ 2003-10-10 16:21 UTC (permalink / raw)


"Stephen Leake" <Stephe.Leake@nasa.gov> wrote in message
news:uzng9f7ej.fsf@nasa.gov...
> Tagged types and full limited types are always passed by reference,
> because it almost always matters for them.

Also, tagged types are almost certainly 2 words+ in size (word <=> 32-bits).
Even
in Ada83 (at least in any implementation I saw) types of this size (or
greater) were
always passed by reference, for efficiency, though the standard didn't
mandate it.





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

* Re: Modes (was unbounded_string)
  2003-10-10  8:27 ` Modes (was unbounded_string) Andrew Carroll
  2003-10-10  9:15   ` Dmitry A. Kazakov
  2003-10-10 15:18   ` Stephen Leake
@ 2003-10-10 19:06   ` Jeffrey Carter
  2003-10-13  9:33     ` Dmitry A. Kazakov
  2 siblings, 1 reply; 15+ messages in thread
From: Jeffrey Carter @ 2003-10-10 19:06 UTC (permalink / raw)


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




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

* Re: Modes (was unbounded_string)
  2003-10-10  9:15   ` Dmitry A. Kazakov
@ 2003-10-11  7:16     ` Simon Wright
  2003-10-13  9:28       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2003-10-11  7:16 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> writes:

> declare  -- I need the value of QUERY_STRING here
>    Temp : String renames Getenv ("QUERY_STRING").all;
>       -- Temp is an alias to the env-string. You cannot modify it.
>       -- Yet it is not a pointer. An analogue would be C++ reference
> begin
>    ... -- Doing with Temp everything I can to do to
>        -- a constant String
> end; -- I don't need it anymore

Actually you *can* modify it:

   with Ada.Text_IO; use Ada.Text_IO;
   with GNAT.OS_Lib; use GNAT.OS_Lib;

   procedure Env is
      Temp : String renames Getenv ("COLDFRAME").all;
   begin
      Temp (1) := 'x';
      Put_Line (Temp);
   end Env;

then

   smaug.pushface.org[5]$ COLDFRAME=foo ./env
   xoo

(GNAT 3.16a1)

Should GNAT.OS_Lib.Getenv have been defined as returning a constant
string access?

   type Constant_String_Access is access constant String;




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

* Re: Modes (was unbounded_string)
  2003-10-11  7:16     ` Simon Wright
@ 2003-10-13  9:28       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2003-10-13  9:28 UTC (permalink / raw)


On 11 Oct 2003 08:16:39 +0100, Simon Wright <simon@pushface.org>
wrote:

>Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> writes:
>
>> declare  -- I need the value of QUERY_STRING here
>>    Temp : String renames Getenv ("QUERY_STRING").all;
>>       -- Temp is an alias to the env-string. You cannot modify it.
>>       -- Yet it is not a pointer. An analogue would be C++ reference
>> begin
>>    ... -- Doing with Temp everything I can to do to
>>        -- a constant String
>> end; -- I don't need it anymore
>
>Actually you *can* modify it:
>
>   with Ada.Text_IO; use Ada.Text_IO;
>   with GNAT.OS_Lib; use GNAT.OS_Lib;
>
>   procedure Env is
>      Temp : String renames Getenv ("COLDFRAME").all;
>   begin
>      Temp (1) := 'x';
>      Put_Line (Temp);
>   end Env;
>
>then
>
>   smaug.pushface.org[5]$ COLDFRAME=foo ./env
>   xoo
>
>(GNAT 3.16a1)
>
>Should GNAT.OS_Lib.Getenv have been defined as returning a constant
>string access?
>
>   type Constant_String_Access is access constant String;

No, if Jeffrey Carter (see his post) is right and the result is
presently allocated on the heap, then it is a very bad design.

Clearly Getenv should either return an Unbounded_String or a plain
String.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: Modes (was unbounded_string)
  2003-10-10 19:06   ` Jeffrey Carter
@ 2003-10-13  9:33     ` Dmitry A. Kazakov
  2003-10-13  9:40       ` Stephane Richard
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2003-10-13  9:33 UTC (permalink / raw)


On Fri, 10 Oct 2003 19:06:00 GMT, Jeffrey Carter <spam@spam.com>
wrote:

>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.

Awful, I didn't expected that from ACT. The design above is definitely
not Ada's idiom.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: Modes (was unbounded_string)
  2003-10-13  9:33     ` Dmitry A. Kazakov
@ 2003-10-13  9:40       ` Stephane Richard
  2003-10-13 10:12         ` Dmitry A. Kazakov
  2003-10-15  2:16         ` Warren W. Gay VE3WWG
  0 siblings, 2 replies; 15+ messages in thread
From: Stephane Richard @ 2003-10-13  9:40 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1193 bytes --]

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:94skovca8efqisiip65q37of63g28n1284@4ax.com...
> On Fri, 10 Oct 2003 19:06:00 GMT, Jeffrey Carter <spam@spam.com>
> wrote:
>
> >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.
>
> Awful, I didn't expected that from ACT. The design above is definitely
> not Ada's idiom.
>
> ---
> Regards,
> Dmitry Kazakov
> www.dmitry-kazakov.de

Perhaps as in many OS it's the only way as the OS (probably written in C or
some other language simply returns it this way?

-- 
St�phane Richard
"Ada World" Webmaster
http://www.adaworld.com







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

* Re: Modes (was unbounded_string)
  2003-10-13  9:40       ` Stephane Richard
@ 2003-10-13 10:12         ` Dmitry A. Kazakov
  2003-10-15  2:16         ` Warren W. Gay VE3WWG
  1 sibling, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2003-10-13 10:12 UTC (permalink / raw)


On Mon, 13 Oct 2003 09:40:39 GMT, "Stephane Richard"
<stephane.richard@verizon.net> wrote:

>"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>news:94skovca8efqisiip65q37of63g28n1284@4ax.com...
>> On Fri, 10 Oct 2003 19:06:00 GMT, Jeffrey Carter <spam@spam.com>
>> wrote:
>>
>> >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.
>>
>> Awful, I didn't expected that from ACT. The design above is definitely
>> not Ada's idiom.
>>
>> ---
>> Regards,
>> Dmitry Kazakov
>> www.dmitry-kazakov.de
>
>Perhaps as in many OS it's the only way as the OS (probably written in C or
>some other language simply returns it this way?

In which way? Neither Win32 nor UNIX getenv require to call free on
the result. It just returns a pointer to some chunk of memory which
probably cannot be deallocated at all. Then even if a particular OS
requires further deallocation then it is not Ada's deallocation. It is
freeing resources, which has nothing to do with calling a deallocator
on the result. If a resource has to be freed then we either

1. return a copy and free the resource before return;

2. return a controlled object, which will free the resource upon
destruction.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: Modes (was unbounded_string)
  2003-10-10 15:18   ` Stephen Leake
  2003-10-10 16:21     ` Martin Dowie
@ 2003-10-14 18:47     ` Craig Carey
  1 sibling, 0 replies; 15+ messages in thread
From: Craig Carey @ 2003-10-14 18:47 UTC (permalink / raw)



On 10 Oct 2003 11:18:28 -0400, Stephen Leake wrote:
>"Andrew Carroll" wrote:
...
>Tagged types and full limited types are always passed by reference,
>because it almost always matters for them.
...

Not really true.
It could be if AARM/RM 12.4(8) was deleted:

  12.4 Formal Objects
    (8.) The type of a generic formal object of mode in shall be
       nonlimited.
    (8.a) Reason: Since a generic formal object is like a constant
       of mode in initialized to the value of the actual, a
       limited type would not make sense, since initializing a
       constant is not allowed for a limited type. That is, generic
       formal objects of mode in are passed by copy, and limited
       types are not supposed to be copied.
   http://www.adaic.org/standards/95aarm/html/AA-12-4.html

Excerpt from AI-00318 ("Returning [limited] objects without copying"):

| From: Randy Brukardt
| Sent: Thursday, February 7, 2002,  3:05 PM
|
| Here is an example that came up in Claw where we really wanted
| constants of a limited type:
|
| [...] its the original problem all over again), so we had to turn that
| into a variable and initialize it component-by-component in the package
| body's elaboration code:
|
|       Standard_Classes_Root : Key_Type;
|
|       function Classes_Root return Key_Type is
|       begin
|          return Standard_Classes_Root;
|       end Classes_Root;
|
|    begin
|       Standard_Classes_Root.Handle := 16#80000000#;  -- Magic number
|       Standard_Classes_Root.Predefined_Key => True;
|       ...
|
| Which is essentially how it is today.
|
| This turned into such a mess that we gave up deriving from it altogether,
  ...
|
| I certainly hope that newcomers to Ada don't run into a problem like this,
| because it is a classic "stupid language" problem.
|
| Simply having a way to initialize a limited constant with an aggregate
| would be sufficient to fix this problem. "Constructor functions" might
| add orthogonality, but seem unnecessary to solve the problem of being
| able to have constants as part of an abstraction's specification.
|

To bypass the restriction of 12.4(8), an "access constant" [read-only]
pointer to the "aliased" unchanging variable would be passed in:


   generic
      type Number is limited private;    --  "limited" stops assigning

      Zero        : in Num;  --  Illegal.
                          --  Here is a workaround:
      type Num_Const_Ptr is access constant Num;
      Zero        :  Num_Const_Ptr;
      ...
   package

Here is some text from AI-00287 (topic "Limited Aggregates Allowed"):

| How do you capture the result of a function call?  You put it in a
| constant: "X: constant T := F(...);". But if it's limited, you have to
| *rename* it: "X: T renames F(...);". Again, that's not something that
| would naturally occur to a beginner -- and the beginner would rightly
| look upon it as a "trick" or a "workaround".




>You can't specify the parameter passing mechanism, except by making
>the type tagged or fully limited.

What about putting "aliased" keyword into the record's definition(?).

----

Corrupted elections in USA:

   http://news.independent.co.uk/world/americas/story.jsp?story=452972


  "some of the code downright suspect - for example, an overtly
   meaningless instruction to divide the number of write-in votes by 1.
   ...
  "Most suspect of all was the governor's race in Alabama, where the
   incumbent Democrat, Don Siegelman, was initially declared the winner.
   Sometime after midnight, when polling station observers and most staff
   had gone home, the probate judge responsible for elections in rural
   Baldwin County suddenly "discovered" that Mr Siegelman had been
   awarded 7,000 votes too many. ... the change was enough to hand
   victory to his Republican challenger, ... the state's Republican
   attorney general refused to authorise a recount or any independent
   ballot inspection."

The San Mateo county assessor (Slocum) has some information on
the need for correct and verificable results from USA elections:

   http://www.warrenslocum.com/





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

* Re: Modes (was unbounded_string)
  2003-10-13  9:40       ` Stephane Richard
  2003-10-13 10:12         ` Dmitry A. Kazakov
@ 2003-10-15  2:16         ` Warren W. Gay VE3WWG
  2003-10-15  3:36           ` Jeff C,
  1 sibling, 1 reply; 15+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-10-15  2:16 UTC (permalink / raw)


"Stephane Richard" <stephane.richard@verizon.net> wrote in message
news:rquib.4914$zw4.1688@nwrdny01.gnilink.net...
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:94skovca8efqisiip65q37of63g28n1284@4ax.com...
> > On Fri, 10 Oct 2003 19:06:00 GMT, Jeffrey Carter <spam@spam.com>
> > wrote:
> >
> > >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.
> >
> > Awful, I didn't expected that from ACT. The design above is definitely
> > not Ada's idiom.
...
> Perhaps as in many OS it's the only way as the OS (probably written in C or
> some other language simply returns it this way?


Well, C returns a pointer, if you use getenv(2). However, there is no reason
that ACT could not have converted this into a normal Ada string, which is
what I would have expected. Even in C, you are really expected to use
putenv or setenv to make a change. However, programmers have been
known to "cheat" and modify the string that the getenv pointer points to,
which works provided that the string does not require more length. But
even in C terms, IMHO, this is a bad practice.

-- 
Warren W. Gay
http://home.cogeco.ca/~ve3wwg





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

* Re: Modes (was unbounded_string)
  2003-10-15  2:16         ` Warren W. Gay VE3WWG
@ 2003-10-15  3:36           ` Jeff C,
  2003-10-16 16:45             ` Warren W. Gay VE3WWG
  0 siblings, 1 reply; 15+ messages in thread
From: Jeff C, @ 2003-10-15  3:36 UTC (permalink / raw)



"Warren W. Gay VE3WWG" <ve3wwg_nospam@cogeco.ca> wrote in message
news:Mb2jb.8531> Well, C returns a pointer, if you use getenv(2). However,
there is no reason
> that ACT could not have converted this into a normal Ada string, which is
> what I would have expected. Even in C, you are really expected to use
> putenv or setenv to make a change. However, programmers have been
> known to "cheat" and modify the string that the getenv pointer points to,
> which works provided that the string does not require more length. But
> even in C terms, IMHO, this is a bad practice.
>


Never assume that there is "no reason" for ACT or anyone else for that
matter doing something without
at least quickly looking at it. The start of the package says

-- This package tends to use fairly low-level Ada in order to not bring
-- in large portions of the RTL. For example, functions return access
-- to string as part of avoiding functions returning unconstrained types.


gnat.os_lib is useful but it probably should not be generally used within
you code. It certainly would
be nice if ACT provided a "thicker" version of the package (and perhaps if a
few customers ask
for it they will) but it appears that they had their reasons whey they
originally set this up.





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

* Re: Modes (was unbounded_string)
  2003-10-15  3:36           ` Jeff C,
@ 2003-10-16 16:45             ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 15+ messages in thread
From: Warren W. Gay VE3WWG @ 2003-10-16 16:45 UTC (permalink / raw)


Jeff C, wrote:

> "Warren W. Gay VE3WWG" <ve3wwg_nospam@cogeco.ca> wrote in message
> news:Mb2jb.8531> Well, C returns a pointer, if you use getenv(2). However,
> there is no reason
> 
>>that ACT could not have converted this into a normal Ada string, which is
>>what I would have expected. Even in C, you are really expected to use
>>putenv or setenv to make a change. However, programmers have been
>>known to "cheat" and modify the string that the getenv pointer points to,
>>which works provided that the string does not require more length. But
>>even in C terms, IMHO, this is a bad practice.
> 
> Never assume that there is "no reason" for ACT or anyone else for that
> matter doing something without
> at least quickly looking at it. The start of the package says

Well, you assumed that I "assumed" there was "no reason". ;-)  I
never assumed "that" -- I simply did not understand the "why"
for it, which you now have cleared up 8-)

> -- This package tends to use fairly low-level Ada in order to not bring
> -- in large portions of the RTL. For example, functions return access
> -- to string as part of avoiding functions returning unconstrained types.
> 
> gnat.os_lib is useful but it probably should not be generally used within
> you code. It certainly would
> be nice if ACT provided a "thicker" version of the package (and perhaps if a
> few customers ask
> for it they will) but it appears that they had their reasons whey they
> originally set this up.

So now, we all know why B-)
-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




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

end of thread, other threads:[~2003-10-16 16:45 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20031010074015.761204C40C1@lovelace.ada-france.org>
2003-10-10  8:27 ` Modes (was unbounded_string) Andrew Carroll
2003-10-10  9:15   ` Dmitry A. Kazakov
2003-10-11  7:16     ` Simon Wright
2003-10-13  9:28       ` Dmitry A. Kazakov
2003-10-10 15:18   ` Stephen Leake
2003-10-10 16:21     ` Martin Dowie
2003-10-14 18:47     ` Craig Carey
2003-10-10 19:06   ` Jeffrey Carter
2003-10-13  9:33     ` Dmitry A. Kazakov
2003-10-13  9:40       ` Stephane Richard
2003-10-13 10:12         ` Dmitry A. Kazakov
2003-10-15  2:16         ` Warren W. Gay VE3WWG
2003-10-15  3:36           ` Jeff C,
2003-10-16 16:45             ` Warren W. Gay VE3WWG
     [not found] <20031010094017.680474C40C1@lovelace.ada-france.org>
2003-10-10 10:58 ` Andrew Carroll

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