comp.lang.ada
 help / color / mirror / Atom feed
* Ada and string literals
@ 2013-01-30  0:44 codeallergy
  2013-01-30  7:08 ` Niklas Holsti
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: codeallergy @ 2013-01-30  0:44 UTC (permalink / raw)


hi comp.lang.ada, 

question from a newcomer: Why ada does not allow using a string literal with access type ?

abc : access string := "LITERAL"; -- error.

example with C: http://ideone.com/Ioapww

Thanks 

    Rom B.



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

* Re: Ada and string literals
  2013-01-30  0:44 Ada and string literals codeallergy
@ 2013-01-30  7:08 ` Niklas Holsti
  2013-01-30 11:50   ` Mart van de Wege
  2013-01-30 16:20   ` Robert A Duff
  2013-01-30 22:54 ` codeallergy
  2013-02-01  0:50 ` Shark8
  2 siblings, 2 replies; 29+ messages in thread
From: Niklas Holsti @ 2013-01-30  7:08 UTC (permalink / raw)


On 13-01-30 02:44 , codeallergy wrote:
> hi comp.lang.ada, 
> 
> question from a newcomer: Why ada does not allow using a string literal with access type ?
> 
> abc : access string := "LITERAL"; -- error.

Because, unlike C, Ada does not confuse arrays with pointers.

This is the closest Ada equivalent:

   Literal : aliased constant String := "LITERAL";
   abc     : access constant String := Literal'Access;

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



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

* Re: Ada and string literals
  2013-01-30  7:08 ` Niklas Holsti
@ 2013-01-30 11:50   ` Mart van de Wege
  2013-01-30 13:52     ` Niklas Holsti
                       ` (2 more replies)
  2013-01-30 16:20   ` Robert A Duff
  1 sibling, 3 replies; 29+ messages in thread
From: Mart van de Wege @ 2013-01-30 11:50 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 13-01-30 02:44 , codeallergy wrote:
>> hi comp.lang.ada, 
>> 
>> question from a newcomer: Why ada does not allow using a string
>> literal with access type ?
>> 
>> abc : access string := "LITERAL"; -- error.
>
> Because, unlike C, Ada does not confuse arrays with pointers.
>
> This is the closest Ada equivalent:
>
>    Literal : aliased constant String := "LITERAL";
>    abc     : access constant String := Literal'Access;

More importantly, I cannot see why you would want an access to a string
literal.

Just use the string literal as a normal parameter, and let the compiler
worry about how to handle that.

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Ada and string literals
  2013-01-30 11:50   ` Mart van de Wege
@ 2013-01-30 13:52     ` Niklas Holsti
  2013-01-30 16:09       ` Adam Beneschan
  2013-02-01  0:54       ` Shark8
  2013-01-30 16:52     ` codeallergy
  2013-01-31  9:20     ` ake.ragnar.dahlgren
  2 siblings, 2 replies; 29+ messages in thread
From: Niklas Holsti @ 2013-01-30 13:52 UTC (permalink / raw)


On 13-01-30 13:50 , Mart van de Wege wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> 
>> On 13-01-30 02:44 , codeallergy wrote:
>>> hi comp.lang.ada, 
>>>
>>> question from a newcomer: Why ada does not allow using a string
>>> literal with access type ?
>>>
>>> abc : access string := "LITERAL"; -- error.
>>
>> Because, unlike C, Ada does not confuse arrays with pointers.
>>
>> This is the closest Ada equivalent:
>>
>>    Literal : aliased constant String := "LITERAL";
>>    abc     : access constant String := Literal'Access;
> 
> More importantly, I cannot see why you would want an access to a string
> literal.
> 
> Just use the string literal as a normal parameter, and let the compiler
> worry about how to handle that.

I don't know why the OP wants an access, but I can image a situation
where one needs, for example, to call a subprogram with several string
parameters, which should have different values depending on different
logical conditions, in various combinations. It is then easier to
represent each parameter by local variable that can be assigned
different values in different if-then-else statements, and then use the
local variables as actual parameters in the call.

For example, assume you must call a procedure Foo (A, B: in String), and
A can be either "James" or "John" depending on condition Alpha, while B
can be either "Jill" or "Jennie" depending on condition Beta. You would
like to write something like this:

   -- The following does NOT work:
   ..
   is
      A, B : String;
   begin
      if Alpha then A := "James"; else A := "John"  ; end if;
      if Beta  then B := "Jill";  else B := "Jennie"; end if;
      Foo (A, B);
   ..

That doesn't work, because the declaration of A and B must specify a
length for the string, and then you cannot assign literal strings of
different length to A and B.

If you use string literals directly as parameters, you need different
calls for all combinations:

   if Alpha then
      if Beta then
         Foo ("James", "Jill");
      else
         Foo ("James", "Jennie");

and so on, for a combinatorial number of cases.

Of course you can use Ada.Strings.Unbounded or Ada.Strings.Bounded,
which let you assign strings of different lengths to the same variable,
but accesses to strings are another solution.

In the above simple example one could also use Ada 2012 conditional
expressions:

   Foo (A => (if Alpha then "James" else "John"  ),
        B => (if Beta  then "Jill"  else "Jennie"));

but in more complex cases that no longer works, or not as well as
assigning the actual parameter values to local variables before the call.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



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

* Re: Ada and string literals
  2013-01-30 13:52     ` Niklas Holsti
@ 2013-01-30 16:09       ` Adam Beneschan
  2013-02-01  0:54       ` Shark8
  1 sibling, 0 replies; 29+ messages in thread
From: Adam Beneschan @ 2013-01-30 16:09 UTC (permalink / raw)


On Wednesday, January 30, 2013 5:52:58 AM UTC-8, Niklas Holsti wrote:

> > More importantly, I cannot see why you would want an access to a string
> > literal.
> 
> > Just use the string literal as a normal parameter, and let the compiler
> > worry about how to handle that.
> 
> I don't know why the OP wants an access, but I can image a situation
> where one needs, for example, to call a subprogram with several string
> parameters, which should have different values depending on different
> logical conditions, in various combinations. It is then easier to
> represent each parameter by local variable that can be assigned
> different values in different if-then-else statements, and then use the
> local variables as actual parameters in the call....

Another fairly common use case is a constant array whose values are string literals.  

By the way, if you use an "access constant string" type, I believe that compilers should, if possible, work things out so that if the type of

    new string' ("Literal")

is an access-constant-string, the compiler will generate a "literal" pointer that points to constant data loaded together with the code, so that the NEW won't cause any allocation or any other code to be run at runtime.  This isn't a requirement, but it's recommended.  That would result in something equivalent to the situation in C, without any unnecessary overhead.  You'd have to make sure you don't try to convert this access type to an access-[not-constant]-string type, though; that isn't allowed for obvious reasons.

                           -- Adam





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

* Re: Ada and string literals
  2013-01-30  7:08 ` Niklas Holsti
  2013-01-30 11:50   ` Mart van de Wege
@ 2013-01-30 16:20   ` Robert A Duff
  2013-02-01 13:20     ` Stephen Leake
  1 sibling, 1 reply; 29+ messages in thread
From: Robert A Duff @ 2013-01-30 16:20 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 13-01-30 02:44 , codeallergy wrote:
>> hi comp.lang.ada, 
>> 
>> question from a newcomer: Why ada does not allow using a string
>> literal with access type ?
>>
>> abc : access string := "LITERAL"; -- error.
>
> Because, unlike C, Ada does not confuse arrays with pointers.
>
> This is the closest Ada equivalent:
>
>    Literal : aliased constant String := "LITERAL";
>    abc     : access constant String := Literal'Access;

That works, but this seems like a closer equivalent to me:

    Abc : access constant String := new String'("LITERAL");

Ada ought to allow:

    Abc : access constant String := "LITERAL"'Access;

with or without the "constant", as a shorthand for the above.

Suppose you want an array of strings.  Well, you can't have
one in Ada, except in the unusual case where they all happen
to have the same length.  So you use array of access to string.

    Colors : constant String_Sequence :=
        ("red"'Access, -- This is not Ada!
         "orange"'Access,
         "dark green"'Access,
         ...);

That gets pretty tedious if you declare a name for each color.

I'd allow arrays of Strings, though, but that's even less Ada-like.

- Bob



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

* Re: Ada and string literals
  2013-01-30 11:50   ` Mart van de Wege
  2013-01-30 13:52     ` Niklas Holsti
@ 2013-01-30 16:52     ` codeallergy
  2013-01-30 17:19       ` Adam Beneschan
                         ` (4 more replies)
  2013-01-31  9:20     ` ake.ragnar.dahlgren
  2 siblings, 5 replies; 29+ messages in thread
From: codeallergy @ 2013-01-30 16:52 UTC (permalink / raw)


Okay. assuming dat we use GNAT 2012

Literal1 : aliased constant String := "LITERAL"; 
Literal2 : aliased constant String := "LITERAL"; 
Literal3 : aliased constant String := "LITERAL"; 

how the above code is handled ?

compiler duplicate the string three times into the data section or
the three constants will share the same string or
one string into the data section but duplicated at the run time ?



another question: how free a object from a procedure ?
 
example:
procedure Free_Abc (Target : access String)
is
begin
   GNAT.Strings.Free(Target); -- error
end Free_Abc;

this code produce the error: actual for "X" must be a variable

why disallow that ?

thanks,
    Rom B.



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

* Re: Ada and string literals
  2013-01-30 16:52     ` codeallergy
@ 2013-01-30 17:19       ` Adam Beneschan
  2013-01-30 20:02       ` Simon Wright
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 29+ messages in thread
From: Adam Beneschan @ 2013-01-30 17:19 UTC (permalink / raw)


On Wednesday, January 30, 2013 8:52:32 AM UTC-8, codeallergy wrote:
> Okay. assuming dat we use GNAT 2012
> 
> Literal1 : aliased constant String := "LITERAL"; 
> Literal2 : aliased constant String := "LITERAL"; 
> Literal3 : aliased constant String := "LITERAL"; 
> 
> how the above code is handled ?
> 
> compiler duplicate the string three times into the data section or
> the three constants will share the same string or
> one string into the data section but duplicated at the run time ?

I don't know how GNAT handles it; but in Ada, having the string objects share the same memory causes a problem if the program later compares the 'Access of two different objects.  Ada says they're supposed to be unequal, but I think that would be hard to do if the string literals shared the same memory.  (I can think of ways to do this by adding some additional data to the access values, but that could easily result in way more overhead than just duplicating the strings would take up.)


> another question: how free a object from a procedure ?
> 
> example:
> 
> procedure Free_Abc (Target : access String)
> is
> begin
>    GNAT.Strings.Free(Target); -- error
> end Free_Abc;
> 
> this code produce the error: actual for "X" must be a variable
> 
> why disallow that ?

Because the definition of Free is that you give it an access variable, it frees the storage, then it sets the variable to null.  Target is basically a read-only value in this procedure, so you can't set it to null.  You can get around it easily enough by declaring a Temp variable and then

   Temp := Target;
   GNAT.Strings.Free(Temp);

But then whoever called Free_Abc may still have a variable that points to a string that no longer exists.  So you have to be careful.  I don't really recommend having a procedure such as Free_Abc that frees storage and isn't able to set the access to null; better to define a *named* access type that is access-to-String and make it an IN OUT parameter to Free_Abc.

                             -- Adam



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

* Re: Ada and string literals
  2013-01-30 16:52     ` codeallergy
  2013-01-30 17:19       ` Adam Beneschan
@ 2013-01-30 20:02       ` Simon Wright
  2013-01-30 20:19         ` Georg Bauhaus
  2013-01-30 22:06       ` Robert A Duff
                         ` (2 subsequent siblings)
  4 siblings, 1 reply; 29+ messages in thread
From: Simon Wright @ 2013-01-30 20:02 UTC (permalink / raw)


codeallergy <romainbeckers@gmail.com> writes:

> Okay. assuming dat we use GNAT 2012
>
> Literal1 : aliased constant String := "LITERAL"; 
> Literal2 : aliased constant String := "LITERAL"; 
> Literal3 : aliased constant String := "LITERAL"; 
>
> how the above code is handled ?
>
> compiler duplicate the string three times into the data section or the
> three constants will share the same string or one string into the data
> section but duplicated at the run time ?

There are three occurences of the string in the data section.

Of course, there may be some GCC option to merge the strings - there's
probably an option to make toast, come to that.



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

* Re: Ada and string literals
  2013-01-30 20:02       ` Simon Wright
@ 2013-01-30 20:19         ` Georg Bauhaus
  0 siblings, 0 replies; 29+ messages in thread
From: Georg Bauhaus @ 2013-01-30 20:19 UTC (permalink / raw)


On 30.01.13 21:02, Simon Wright wrote:
> Of course, there may be some GCC option to merge the strings - there's
> probably an option to make toast, come to that.

Yes, GCC burns enough CPU cycles for making toast when a
mini C99 program uses larger variable length arrays of C99.
I'm building GCC from latests sources hoping I won't need to
report the ICEs I'm seeing on this hard working system.



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

* Re: Ada and string literals
  2013-01-30 16:52     ` codeallergy
  2013-01-30 17:19       ` Adam Beneschan
  2013-01-30 20:02       ` Simon Wright
@ 2013-01-30 22:06       ` Robert A Duff
  2013-01-30 22:10         ` Jeffrey Carter
  2013-02-01 21:16       ` gautier_niouzes
  2013-02-02  1:55       ` Stephen Leake
  4 siblings, 1 reply; 29+ messages in thread
From: Robert A Duff @ 2013-01-30 22:06 UTC (permalink / raw)


codeallergy <romainbeckers@gmail.com> writes:

> Okay. assuming dat we use GNAT 2012
>
> Literal1 : aliased constant String := "LITERAL"; 
> Literal2 : aliased constant String := "LITERAL"; 
> Literal3 : aliased constant String := "LITERAL"; 
>
> how the above code is handled ?
>
> compiler duplicate the string three times into the data section or

Yes, that's the most likely implementation.

> the three constants will share the same string or

That won't work, because Literal1 = Literal2 must be False.
If you leave out "aliased", then the compiler might share.

> one string into the data section but duplicated at the run time ?

That would work, but I don't see why a compiler would do that.

- Bob



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

* Re: Ada and string literals
  2013-01-30 22:06       ` Robert A Duff
@ 2013-01-30 22:10         ` Jeffrey Carter
  2013-01-31  2:23           ` Robert A Duff
  0 siblings, 1 reply; 29+ messages in thread
From: Jeffrey Carter @ 2013-01-30 22:10 UTC (permalink / raw)


On 01/30/2013 03:06 PM, Robert A Duff wrote:
>
> That won't work, because Literal1 = Literal2 must be False.
> If you leave out "aliased", then the compiler might share.

I think there are some attributes missing here.

-- 
Jeff Carter
"I was hobbling along, minding my own business, all of a
sudden, up he comes, cures me! One minute I'm a leper with
a trade, next minute my livelihood's gone! Not so much as a
'by your leave!' You're cured, mate. Bloody do-gooder!"
Monty Python's Life of Brian
76



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

* Re: Ada and string literals
  2013-01-30  0:44 Ada and string literals codeallergy
  2013-01-30  7:08 ` Niklas Holsti
@ 2013-01-30 22:54 ` codeallergy
  2013-02-01  0:50 ` Shark8
  2 siblings, 0 replies; 29+ messages in thread
From: codeallergy @ 2013-01-30 22:54 UTC (permalink / raw)


Thanks for answering.

i reversed the generated code. when u use a literal as a argument like this

    Put_Line("HELLO");
    Abc("HELLO");

the same string from the data section is shared. when you use constants from a package like this

    package Abc is
        str1 : aliased constant String : "LITERAL";
        str2 : aliased constant String : "LITERAL";
    end Abc;

strings are duplicated and put into the data section, aliased or not. when you use constant from a procedure header (dunno how u name that) like this

    procedure Abc
    is
        str1 : aliased constant String : "LITERAL";
    begin
        null;
    end Abc;

if the constant is aliased, the constant is not put into the data section but "hardcoded" and push on the stackframe like this:

    .text:00401FA2  mov dword ptr [ebp-104h], 1
    .text:00401FAC  mov dword ptr [ebp-100h], 7
    .text:00401FB6  mov dword ptr [ebp-0FCh], 4554494Ch ; 4C49544552414C = "LITERAL"
    .text:00401FC0  mov word ptr [ebp-0F8h], 4152h
    .text:00401FC9  mov byte ptr [ebp-0F6h], 4Ch

if not aliased the constant is put into the data section.

    - Rom B.



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

* Re: Ada and string literals
  2013-01-30 22:10         ` Jeffrey Carter
@ 2013-01-31  2:23           ` Robert A Duff
  2013-01-31 15:49             ` Adam Beneschan
  0 siblings, 1 reply; 29+ messages in thread
From: Robert A Duff @ 2013-01-31  2:23 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> On 01/30/2013 03:06 PM, Robert A Duff wrote:
>>
>> That won't work, because Literal1 = Literal2 must be False.
>> If you leave out "aliased", then the compiler might share.
>
> I think there are some attributes missing here.

Oops.  Thanks!

Yes, I meant that Literal1'Access = Literal2'Access must be False.
Same for 'Unchecked_Access.

'[Unchecked_]Access is about object identity.
On the other hand 'Address is not -- two objects can have
the same address without being the same object.

- Bob



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

* Re: Ada and string literals
  2013-01-30 11:50   ` Mart van de Wege
  2013-01-30 13:52     ` Niklas Holsti
  2013-01-30 16:52     ` codeallergy
@ 2013-01-31  9:20     ` ake.ragnar.dahlgren
  2 siblings, 0 replies; 29+ messages in thread
From: ake.ragnar.dahlgren @ 2013-01-31  9:20 UTC (permalink / raw)


On Wednesday, January 30, 2013 12:50:38 PM UTC+1, Mart van de Wege wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes: > On 13-01-30 02:44 , codeallergy wrote: >> hi comp.lang.ada, >> >> question from a newcomer: Why ada does not allow using a string >> literal with access type ? >> >> abc : access string := "LITERAL"; -- error. > > Because, unlike C, Ada does not confuse arrays with pointers. > > This is the closest Ada equivalent: > > Literal : aliased constant String := "LITERAL"; > abc : access constant String := Literal'Access; More importantly, I cannot see why you would want an access to a string literal. Just use the string literal as a normal parameter, and let the compiler worry about how to handle that. Mart -- "We will need a longer wall when the revolution comes." --- AJS, quoting an uncertain source.

The other day I was looking at the Ada code for the GPS (GNAT Programming Studio). This is code taken from the procedure GPS.Main:

subtype String_Access is GNAT.Strings.String_Access;

Home                   : String_Access;
Home_Dir               : Virtual_File; 
Project_Name           : Virtual_File := No_File; 
Prefix                 : String_Access;
Prefix_Dir             : Virtual_File; 
GPS_Home_Dir           : Virtual_File; 
Batch_File             : String_Access; 
Batch_Script           : String_Access; 
Tools_Host             : String_Access; 
Target                 : String_Access; 
Protocol               : String_Access; 
Debugger_Name          : String_Access; 
Startup_Dir            : String_Access; 
About_Contents         : String_Access;
 
The string access type was chosen over the string type for handling strings. Maybe to avoid setting a maximum string length? Performance reasons? Anyways, I think the authors of the GPS are able to give a good motivation of when one prefers the string access type over the ordinary string type.

Best regards,
Åke Ragnar Dahlgren



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

* Re: Ada and string literals
  2013-01-31  2:23           ` Robert A Duff
@ 2013-01-31 15:49             ` Adam Beneschan
  2013-01-31 22:24               ` Robert A Duff
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Beneschan @ 2013-01-31 15:49 UTC (permalink / raw)


On Wednesday, January 30, 2013 6:23:08 PM UTC-8, Robert A Duff wrote:
> Jeffrey Carter writes:

> '[Unchecked_]Access is about object identity.
> On the other hand 'Address is not -- two objects can have
> the same address without being the same object.

However, if two objects have the same 'Address, it's hard to imagine them not having the same 'Access as well, in practice.  There aren't many cases where this is an issue, but:

   procedure P (Addr : in System.Address) is

      X : aliased T;
      for X'Address use Addr;
      pragma Import (Ada, X);

      Y : aliased T;
      for Y'Address use Addr;
      pragma Import (Ada, Y);

      XA : T_Acc := X'Access;
      YA : T_Acc := Y'Access;

      ...

      if XA = YA then ...

   end Proc;

Assuming T is a simple record type, for instance, I can't imagine XA=YA being false in any implementation, even though I believe X and Y are distinct objects by the RM's definitions.  The additional logic and/or storage required to make sure XA /= YA would be unacceptable distributed overhead.

(This may or may not apply to unconstrained String subtypes such as in the example; if an implementation already uses an implicit level of indirection somewhere to implement those, then it may be possible that 'Address would be the same and 'Access different without any additional overhead.)

                               -- Adam 



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

* Re: Ada and string literals
  2013-01-31 15:49             ` Adam Beneschan
@ 2013-01-31 22:24               ` Robert A Duff
  0 siblings, 0 replies; 29+ messages in thread
From: Robert A Duff @ 2013-01-31 22:24 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> On Wednesday, January 30, 2013 6:23:08 PM UTC-8, Robert A Duff wrote:
>
>> '[Unchecked_]Access is about object identity.
>> On the other hand 'Address is not -- two objects can have
>> the same address without being the same object.
>
> However, if two objects have the same 'Address, it's hard to imagine
> them not having the same 'Access as well, in practice.

It's easy to imagine that 'Access is illegal.  ;-)  That was part of my
point: a compiler can place two objects at the same address if
they are not aliased.  For example, if one of them has zero size.
And I wasn't thinking about the case where the user FORCES the
same address as in your example below.

>...  There aren't many cases where this is an issue, but:
>
>    procedure P (Addr : in System.Address) is
>
>       X : aliased T;
>       for X'Address use Addr;
>       pragma Import (Ada, X);
...
> Assuming T is a simple record type, for instance, I can't imagine
> XA=YA being false in any implementation, even though I believe X and Y
> are distinct objects by the RM's definitions.

For sure.  Are X and Y distinct objects?  I'd say the correct
answer is "Who cares?"  ;-)  Maybe this is a bug in the RM,
but I hope nobody pesters the ARG about it.  IMHO, bugs in the
RM should be reported to ARG only if fixing them would change some
compiler writer's behavior, or change some programmer's behavior.

- Bob



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

* Re: Ada and string literals
  2013-01-30  0:44 Ada and string literals codeallergy
  2013-01-30  7:08 ` Niklas Holsti
  2013-01-30 22:54 ` codeallergy
@ 2013-02-01  0:50 ` Shark8
  2 siblings, 0 replies; 29+ messages in thread
From: Shark8 @ 2013-02-01  0:50 UTC (permalink / raw)


On Tuesday, January 29, 2013 6:44:44 PM UTC-6, codeallergy wrote:
> hi comp.lang.ada, 
> 
> question from a newcomer: Why ada does not allow using a string literal with access type ?
> abc : access string := "LITERAL"; -- error.
> 
> example with C: http://ideone.com/Ioapww
> 
> 
> Thanks 
>     Rom B.

Because a String and an Access String are different types.
You could fix it by saying:
  abc : access string := new String'("LITERAL");
or perhaps more safely:
  def : Aliased String:= "LITERAL";
  abc : access string := def'access;



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

* Re: Ada and string literals
  2013-01-30 13:52     ` Niklas Holsti
  2013-01-30 16:09       ` Adam Beneschan
@ 2013-02-01  0:54       ` Shark8
  2013-02-01  9:03         ` Niklas Holsti
  1 sibling, 1 reply; 29+ messages in thread
From: Shark8 @ 2013-02-01  0:54 UTC (permalink / raw)


On Wednesday, January 30, 2013 7:52:58 AM UTC-6, Niklas Holsti wrote:
> 
>    -- The following does NOT work:
>    ..
>    is
>       A, B : String;
>    begin
>       if Alpha then A := "James"; else A := "John"  ; end if;
>       if Beta  then B := "Jill";  else B := "Jennie"; end if;
>       Foo (A, B);
>    ..

But it's unneeded in Ada 2012 -- use the following:
Foo(
  Param_1 => (if alpha then "James" else "John"),
  Param_2 => (if beta then "Jill" else "Jennie")
);



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

* Re: Ada and string literals
  2013-02-01  0:54       ` Shark8
@ 2013-02-01  9:03         ` Niklas Holsti
  2013-02-01 14:58           ` Shark8
  0 siblings, 1 reply; 29+ messages in thread
From: Niklas Holsti @ 2013-02-01  9:03 UTC (permalink / raw)


On 13-02-01 02:54 , Shark8 wrote:
> On Wednesday, January 30, 2013 7:52:58 AM UTC-6, Niklas Holsti wrote:
>>
>>    -- The following does NOT work:
>>    ..
>>    is
>>       A, B : String;
>>    begin
>>       if Alpha then A := "James"; else A := "John"  ; end if;
>>       if Beta  then B := "Jill";  else B := "Jennie"; end if;
>>       Foo (A, B);
>>    ..
> 
> But it's unneeded in Ada 2012 -- use the following:
> Foo(
>   Param_1 => (if alpha then "James" else "John"),
>   Param_2 => (if beta then "Jill" else "Jennie")
> );

I guess you didn't read to the end of my post before replying.

Using Ada 2012 conditional expressions in the actual parameters works in
this simple example, but become cumbersome (e.g. because of duplicated
conditions and nested conditions) in more complex cases.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



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

* Re: Ada and string literals
  2013-01-30 16:20   ` Robert A Duff
@ 2013-02-01 13:20     ` Stephen Leake
  2013-02-01 14:49       ` Robert A Duff
  2013-02-01 17:23       ` Dmitry A. Kazakov
  0 siblings, 2 replies; 29+ messages in thread
From: Stephen Leake @ 2013-02-01 13:20 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> Suppose you want an array of strings.  Well, you can't have
> one in Ada, except in the unusual case where they all happen
> to have the same length.  So you use array of access to string.
>
>     Colors : constant String_Sequence :=
>         ("red"'Access, -- This is not Ada!
>          "orange"'Access,
>          "dark green"'Access,
>          ...);
>
> That gets pretty tedious if you declare a name for each color.

That's what "+" is for:

   function "+" (Item : in String) return access constant String
   is begin
      return new String'(Item);
   end "+";

     Colors : constant String_Sequence :=
         (+"red", -- This _is_ Ada!
          +"orange",
          +"dark green",
          ...);

I would be _very_ nice if that definition of "+" was in Ada.Strings
somewhere.

Of course, if you also want the non-constant equivalent:

   function "+" (Item : in String) return access String

then can you have ambiguity problems.

-- 
-- Stephe



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

* Re: Ada and string literals
  2013-02-01 13:20     ` Stephen Leake
@ 2013-02-01 14:49       ` Robert A Duff
  2013-02-01 17:23       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 29+ messages in thread
From: Robert A Duff @ 2013-02-01 14:49 UTC (permalink / raw)


Stephen Leake <stephen_leake@stephe-leake.org> writes:

> That's what "+" is for:

Yeah, I use that technique sometimes.  But it feels more like
a "workaround" than a "technique".

> I would be _very_ nice if that definition of "+" was in Ada.Strings
> somewhere.

It would be even nicer if you could declare an array-of-String.

- Bob



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

* Re: Ada and string literals
  2013-02-01  9:03         ` Niklas Holsti
@ 2013-02-01 14:58           ` Shark8
  0 siblings, 0 replies; 29+ messages in thread
From: Shark8 @ 2013-02-01 14:58 UTC (permalink / raw)


On Friday, February 1, 2013 3:03:38 AM UTC-6, Niklas Holsti wrote:
> On 13-02-01 02:54 , Shark8 wrote:
> 
> I guess you didn't read to the end of my post before replying.

Guilty.
I've been writing up some tutorials for Ada 2012 and, like an overexcited schoolboy, thought "I know this, I know this!" in the middle of the post.

*insert embarrassed smile*
Sorry about that.

> 
> Using Ada 2012 conditional expressions in the actual parameters works in
> this simple example, but become cumbersome (e.g. because of duplicated
> conditions and nested conditions) in more complex cases.

True, though you can somewhat mitigate that with some structuring.



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

* Re: Ada and string literals
  2013-02-01 13:20     ` Stephen Leake
  2013-02-01 14:49       ` Robert A Duff
@ 2013-02-01 17:23       ` Dmitry A. Kazakov
  2013-02-01 20:22         ` Robert A Duff
  1 sibling, 1 reply; 29+ messages in thread
From: Dmitry A. Kazakov @ 2013-02-01 17:23 UTC (permalink / raw)


On Fri, 01 Feb 2013 08:20:24 -0500, Stephen Leake wrote:

> That's what "+" is for:
> 
>    function "+" (Item : in String) return access constant String
>    is begin
>       return new String'(Item);
>    end "+";
> 
>      Colors : constant String_Sequence :=
>          (+"red", -- This _is_ Ada!
>           +"orange",
>           +"dark green",
>           ...);

What about:

   function "&" (Left, Right : String) return String_Sequence is
   begin
      return (new String'(Left), new String'(Right));
   end "&";

   function "&" (Left : String; Right : String_Sequence)
      return String_Sequence is
   begin
      return String_Sequence'(1 => new String'(Left)) & Right;
   end "&";

   Colors : constant String_Sequence := "red" & "orange" & "dark green";

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Ada and string literals
  2013-02-01 17:23       ` Dmitry A. Kazakov
@ 2013-02-01 20:22         ` Robert A Duff
  2013-02-01 22:03           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 29+ messages in thread
From: Robert A Duff @ 2013-02-01 20:22 UTC (permalink / raw)


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

> On Fri, 01 Feb 2013 08:20:24 -0500, Stephen Leake wrote:
>
>> That's what "+" is for:
>> 
>>    function "+" (Item : in String) return access constant String
>>    is begin
>>       return new String'(Item);
>>    end "+";
>> 
>>      Colors : constant String_Sequence :=
>>          (+"red", -- This _is_ Ada!
>>           +"orange",
>>           +"dark green",
>>           ...);
>
> What about:
>
>    function "&" (Left, Right : String) return String_Sequence is
>    begin
>       return (new String'(Left), new String'(Right));
>    end "&";
>
>    function "&" (Left : String; Right : String_Sequence)
>       return String_Sequence is
>    begin
>       return String_Sequence'(1 => new String'(Left)) & Right;
>    end "&";
>
>    Colors : constant String_Sequence := "red" & "orange" & "dark green";

Looks dangerous to me.  If I'm not mistaken, you have a bug:  ;-)
the above sets Colors to a 2-element array containing a pointer
to "redorange" and a pointer to "dark green".  The first "&" in Colors
calls the predefined String one, and the second "&" calls the first
"&" body shown above.  The second body is never called.

I suppose that could be fixed, but we're getting further and
further from something where the compiler is likely to generate
a statically-allocated table of pointers to statically-allocated
strings.

- Bob



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

* Re: Ada and string literals
  2013-01-30 16:52     ` codeallergy
                         ` (2 preceding siblings ...)
  2013-01-30 22:06       ` Robert A Duff
@ 2013-02-01 21:16       ` gautier_niouzes
  2013-02-02  1:55       ` Stephen Leake
  4 siblings, 0 replies; 29+ messages in thread
From: gautier_niouzes @ 2013-02-01 21:16 UTC (permalink / raw)


Le mercredi 30 janvier 2013 17:52:32 UTC+1, codeallergy a écrit :

> another question: how free a object from a procedure ?

with Ada.Unchecked_Deallocation;
...
  procedure Free is new Ada.Unchecked_Deallocation(String, String_Access);

> example:
> procedure Free_Abc (Target : access String)
> is
> begin
>    GNAT.Strings.Free(Target); -- error
> end Free_Abc;
> 
> this code produce the error: actual for "X" must be a variable
> 
> why disallow that ?

The access parameter seems to be like an "in" parameter and treated as a local constant (only a guess, I don't use access parameters).
What you pass as an "in" parameter is not certainly a variable
You could have a call like Free_Abc(null);
Similarly you could have

procedure Do_something(x: in Integer) is
begin
  x:= x + 1; -- same error
end;

But with the "in" parameter, you could have a call like
Do_something(1234);
which makes the x:= x + 1 nonsensical.

Cheers
Gautier



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

* Re: Ada and string literals
  2013-02-01 20:22         ` Robert A Duff
@ 2013-02-01 22:03           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 29+ messages in thread
From: Dmitry A. Kazakov @ 2013-02-01 22:03 UTC (permalink / raw)


On Fri, 01 Feb 2013 15:22:09 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Fri, 01 Feb 2013 08:20:24 -0500, Stephen Leake wrote:
>>
>>> That's what "+" is for:
>>> 
>>>    function "+" (Item : in String) return access constant String
>>>    is begin
>>>       return new String'(Item);
>>>    end "+";
>>> 
>>>      Colors : constant String_Sequence :=
>>>          (+"red", -- This _is_ Ada!
>>>           +"orange",
>>>           +"dark green",
>>>           ...);
>>
>> What about:
>>
>>    function "&" (Left, Right : String) return String_Sequence is
>>    begin
>>       return (new String'(Left), new String'(Right));
>>    end "&";
>>
>>    function "&" (Left : String; Right : String_Sequence)
>>       return String_Sequence is
>>    begin
>>       return String_Sequence'(1 => new String'(Left)) & Right;
>>    end "&";
>>
>>    Colors : constant String_Sequence := "red" & "orange" & "dark green";
> 
> Looks dangerous to me.  If I'm not mistaken, you have a bug:  ;-)
> the above sets Colors to a 2-element array containing a pointer
> to "redorange" and a pointer to "dark green".  The first "&" in Colors
> calls the predefined String one, and the second "&" calls the first
> "&" body shown above.  The second body is never called.

We could use "/" or "+" instead of "&".

   Colors : constant String_Sequence := "red" / "orange" / "dark green";

(still better than ugly prefix "+")

> I suppose that could be fixed, but we're getting further and
> further from something where the compiler is likely to generate
> a statically-allocated table of pointers to statically-allocated
> strings.

Which is not likely the proper way for the problem at hand, anyway. I guess
that the solution for what OP is supposedly doing would be an initialized
map or table with string keys. Such things are initialized in the package
body using "begin ... end" construct.

It would be very helpful if Ada allowed that through user-defined static
operations, but that is a story for another day.
 
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Ada and string literals
  2013-01-30 16:52     ` codeallergy
                         ` (3 preceding siblings ...)
  2013-02-01 21:16       ` gautier_niouzes
@ 2013-02-02  1:55       ` Stephen Leake
  2013-02-02 14:30         ` Robert A Duff
  4 siblings, 1 reply; 29+ messages in thread
From: Stephen Leake @ 2013-02-02  1:55 UTC (permalink / raw)


codeallergy <romainbeckers@gmail.com> writes:

> another question: how free a object from a procedure ?
>  
> example:
> procedure Free_Abc (Target : access String)
> is
> begin
>    GNAT.Strings.Free(Target); -- error
> end Free_Abc;
>
> this code produce the error: actual for "X" must be a variable
>
> why disallow that ?

Because Free sets its argument to null, which it can't do if it's not a
variable.

Setting the argument to null helps avoid dangling pointers.

-- 
-- Stephe



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

* Re: Ada and string literals
  2013-02-02  1:55       ` Stephen Leake
@ 2013-02-02 14:30         ` Robert A Duff
  0 siblings, 0 replies; 29+ messages in thread
From: Robert A Duff @ 2013-02-02 14:30 UTC (permalink / raw)


Stephen Leake <stephen_leake@stephe-leake.org> writes:

> Setting the argument to null helps avoid dangling pointers.

It does.  But I doubt it helps a lot, because it only detects
the most obvious case, where you free X and then refer to
X.all.  The more subtle bug is when you free X and then refer
to Y.all (or free Y).  Setting X to null is no help there.

- Bob



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

end of thread, other threads:[~2013-02-02 14:30 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-30  0:44 Ada and string literals codeallergy
2013-01-30  7:08 ` Niklas Holsti
2013-01-30 11:50   ` Mart van de Wege
2013-01-30 13:52     ` Niklas Holsti
2013-01-30 16:09       ` Adam Beneschan
2013-02-01  0:54       ` Shark8
2013-02-01  9:03         ` Niklas Holsti
2013-02-01 14:58           ` Shark8
2013-01-30 16:52     ` codeallergy
2013-01-30 17:19       ` Adam Beneschan
2013-01-30 20:02       ` Simon Wright
2013-01-30 20:19         ` Georg Bauhaus
2013-01-30 22:06       ` Robert A Duff
2013-01-30 22:10         ` Jeffrey Carter
2013-01-31  2:23           ` Robert A Duff
2013-01-31 15:49             ` Adam Beneschan
2013-01-31 22:24               ` Robert A Duff
2013-02-01 21:16       ` gautier_niouzes
2013-02-02  1:55       ` Stephen Leake
2013-02-02 14:30         ` Robert A Duff
2013-01-31  9:20     ` ake.ragnar.dahlgren
2013-01-30 16:20   ` Robert A Duff
2013-02-01 13:20     ` Stephen Leake
2013-02-01 14:49       ` Robert A Duff
2013-02-01 17:23       ` Dmitry A. Kazakov
2013-02-01 20:22         ` Robert A Duff
2013-02-01 22:03           ` Dmitry A. Kazakov
2013-01-30 22:54 ` codeallergy
2013-02-01  0:50 ` Shark8

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