comp.lang.ada
 help / color / mirror / Atom feed
* Bounded String question
@ 2015-11-10 22:00 Serge Robyns
  2015-11-11  0:48 ` Bob Duff
  0 siblings, 1 reply; 36+ messages in thread
From: Serge Robyns @ 2015-11-10 22:00 UTC (permalink / raw)


I'm trying to use bounded strings and I'm facing some issues when I'm trying to use pragma preelaborate in my package.

I'm using bounded strings to store some text data with an upper limit in size.  I've been a little lazy and I'm reusing the same package for different "types".  But I do want to have the different types to be different, so that they cannot be assigned to each other for example.

package Test is
   -- pragma Preelaborate;
   package P_Strings is new Ada.Strings.Bounded.Generic_Bounded_Length (20);

   type T_Client_Name is new P_Strings.Bounded_String;
   type T_Account_Name is new P_Strings.Bounded_String;

....

   No_Client_Name : constant T_Client_Name;
   No_Account_Name : constant T_Account_Name;
...
private
   No_Client_Name : constant T_Client_Name := T_Client_Name (P_Strings.Null_Bounded_String);
   No_Account_Name : constant T_Account_Name := T_Account_Name (P_Strings.Null_Bounded_String);
...

Everything works fine as long as I don't want to use the pragma preelaborate.

When compiling with pragma preelaborate I get the following errors.
non-static constant in preelaborated unit
static expression must have scalar or string type (RM 4.9(2))

I've been trying to find solutions and so far the only one that seems not to complain is when I'm create subtypes and using renames to rename P_Strings.Null_Bounded_String as for example:
subtype T_Client_Name is P_Strings.Bounded_String;
No_Client_Name : T_Client_Name renames P_Strings.Null_Bounded_String; 

However this is defeating my initial purpose of using types.  Because now I can mix T_Client_Name and T_Account_Name, which is now "legal" but makes no sense in my application.

I've been trying to use pragma Preelaborable_Initialization (T_Client_Name) but this seems not to solve it.

Maybe I'm using bounded strings completely wrong.

Some advise is most welcome.


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

* Re: Bounded String question
  2015-11-10 22:00 Bounded String question Serge Robyns
@ 2015-11-11  0:48 ` Bob Duff
  2015-11-11  2:01   ` Jeffrey R. Carter
  2015-11-11 10:52   ` Serge Robyns
  0 siblings, 2 replies; 36+ messages in thread
From: Bob Duff @ 2015-11-11  0:48 UTC (permalink / raw)


Serge Robyns <serge.robyns@gmail.com> writes:

>    No_Client_Name : constant T_Client_Name;

How about:

   function No_Client_Name return T_Client_Name is
      (T_Client_Name (P_Strings.Null_Bounded_String));

?

But why do you need Preelaborate?  It's not all that much use if you use
GNAT's static elaboration model.

> Maybe I'm using bounded strings completely wrong.

Well, I think the Ada.Strings.Bounded package is way overengineered.
So "using Ada.Strings.Bounded" = "using bounded strings wrong".  ;-)
I suggest rolling your own.  No need for generics.

   type Bounded_String (Max_Length : Natural := ...) is limited record
      Length : Natural := 0;
      Chars  : String (1 .. Max_Length);
   end record;

along with a few trivial operations.

- Bob


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

* Re: Bounded String question
  2015-11-11  0:48 ` Bob Duff
@ 2015-11-11  2:01   ` Jeffrey R. Carter
  2015-11-11 15:34     ` Bob Duff
  2015-11-11 10:52   ` Serge Robyns
  1 sibling, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-11  2:01 UTC (permalink / raw)


On 11/10/2015 05:48 PM, Bob Duff wrote:
> 
> I suggest rolling your own.  No need for generics.
> 
>    type Bounded_String (Max_Length : Natural := ...) is limited record
>       Length : Natural := 0;
>       Chars  : String (1 .. Max_Length);
>    end record;

Except that using Natural for Max_Length results in GNAT allocating Integer'Last
characters for Chars, which is unlikely to fit on the stack.

-- 
Jeff Carter
"I'll get broads up here like you wouldn't believe.
Swingers. Freaks. Nymphomaniacs. Dental hygienists."
Play It Again, Sam
125

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

* Re: Bounded String question
  2015-11-11  0:48 ` Bob Duff
  2015-11-11  2:01   ` Jeffrey R. Carter
@ 2015-11-11 10:52   ` Serge Robyns
  2015-11-11 13:43     ` Serge Robyns
  2015-11-11 15:41     ` Bob Duff
  1 sibling, 2 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-11 10:52 UTC (permalink / raw)


Hi Bob,

On Wednesday, 11 November 2015 01:48:43 UTC+1, Bob Duff  wrote:
> How about:
> 
>    function No_Client_Name return T_Client_Name is
>       (T_Client_Name (P_Strings.Null_Bounded_String));

May idea was to have a "constant" and use language construct/semantic to expose that.  I was expecting that the compiler will have more optimization options with such a construct than a dynamic construct like above.
 
> But why do you need Preelaborate?  It's not all that much use if you use
> GNAT's static elaboration model.

Just for the sake of "cleanness" and again using language features to express my intent as per my "expectations".  Even if I would end up using GNAT in all cases.

> > Maybe I'm using bounded strings completely wrong.
> 
> Well, I think the Ada.Strings.Bounded package is way overengineered.
> So "using Ada.Strings.Bounded" = "using bounded strings wrong".  ;-)
> I suggest rolling your own.  No need for generics.
> 
>    type Bounded_String (Max_Length : Natural := ...) is limited record
>       Length : Natural := 0;
>       Chars  : String (1 .. Max_Length);
>    end record;
> 
> along with a few trivial operations.

I tend to agree that the bounded strings seems over-engineered but I'm lacking Ada experience to judge that properly.  However it is indeed a pain to use compared to other languages where I come from, e.g. C.  I don't know why strings are so complex to use in Ada. At various places I've conversions between bounded strings and plain strings in order to offer a consistent API to my modules. Luckily the package already provide a To_String function.  However, I've had to write loads of functions like "To_Client_Name (Name : in String) return T_Client_Name is (T_Client_Name (P_Strings.To_Bounded_String (Name));" as I haven't found a more direct way to convert a string to the type. This with some other oddities in Ada is what do give me a lot of frustrations.  However, I do remain decided to proceed with Ada, as I do believe in its core principles of allowing developing reliable software.

Now with regards to rolling my own, is this not defeating re-use?  Why shall I waste my time on such a feature while I'm having loads of things to do on the application itself.

I've been considering using unbounded strings instead but then I'm dropping the idea of a bounded storage for my entities.  Most of these "strings" ends up in record types which in the end will map to database entities.

> - Bob

Serge

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

* Re: Bounded String question
  2015-11-11 10:52   ` Serge Robyns
@ 2015-11-11 13:43     ` Serge Robyns
  2015-11-11 14:32       ` brbarkstrom
  2015-11-11 17:27       ` Jeffrey R. Carter
  2015-11-11 15:41     ` Bob Duff
  1 sibling, 2 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-11 13:43 UTC (permalink / raw)


On Wednesday, 11 November 2015 11:52:13 UTC+1, Serge Robyns  wrote:
>I've had to write loads of functions like "To_Client_Name (Name : in String) >return T_Client_Name is (T_Client_Name (P_Strings.To_Bounded_String (Name));"  

What does escape my understanding is why can I use To_String with any type defined from P_Strings but have to define all the To_xyz explicitly.  Is there a kind of "hidden" conversion applied in that case?

>I've been considering using unbounded strings instead but then I'm dropping >the idea of a bounded storage for my entities.  Most of these "strings" ends >up in record types which in the end will map to database entities.

I still have the same issue with Bounded Strings anyway.  So no point.

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

* Re: Bounded String question
  2015-11-11 13:43     ` Serge Robyns
@ 2015-11-11 14:32       ` brbarkstrom
  2015-11-11 16:08         ` Serge Robyns
  2015-11-11 17:27       ` Jeffrey R. Carter
  1 sibling, 1 reply; 36+ messages in thread
From: brbarkstrom @ 2015-11-11 14:32 UTC (permalink / raw)


> >I've had to write loads of functions like "To_Client_Name (Name : in String) >return T_Client_Name is (T_Client_Name (P_Strings.To_Bounded_String (Name));"  
> 
> What does escape my understanding is why can I use To_String with any type defined from P_Strings but have to define all the To_xyz explicitly.  Is there a kind of "hidden" conversion applied in that case?
> 
> >I've been considering using unbounded strings instead but then I'm dropping >the idea of a bounded storage for my entities.  Most of these "strings" ends >up in record types which in the end will map to database entities.
> 
> I still have the same issue with Bounded Strings anyway.  So no point.

Probably the sensible approach is not to expect Ada to act like C.  I use
Bounded_Strings constantly and just expect to do the conversion from
Bounded_Strings to plain String (and back).  It's a bit more verbose, but
that may just be one of the costs of strong typing.

I'd also note that P_String seems to be rather close to the type name one
would use in C for a pointer (or an access type in Ada).  Personally, I'd
find that confusing.

Bruce B.


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

* Re: Bounded String question
  2015-11-11  2:01   ` Jeffrey R. Carter
@ 2015-11-11 15:34     ` Bob Duff
  2015-11-11 17:36       ` Jeffrey R. Carter
  2016-03-06 18:59       ` Xavier Petit
  0 siblings, 2 replies; 36+ messages in thread
From: Bob Duff @ 2015-11-11 15:34 UTC (permalink / raw)


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

> On 11/10/2015 05:48 PM, Bob Duff wrote:
>> 
>> I suggest rolling your own.  No need for generics.
>> 
>>    type Bounded_String (Max_Length : Natural := ...) is limited record
>>       Length : Natural := 0;
>>       Chars  : String (1 .. Max_Length);
>>    end record;
>
> Except that using Natural for Max_Length results in GNAT allocating Integer'Last
> characters for Chars, which is unlikely to fit on the stack.

No, the type is limited, so GNAT will allocate space for Max_Length
characters, not Natural'Last characters.

- Bob

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

* Re: Bounded String question
  2015-11-11 10:52   ` Serge Robyns
  2015-11-11 13:43     ` Serge Robyns
@ 2015-11-11 15:41     ` Bob Duff
  1 sibling, 0 replies; 36+ messages in thread
From: Bob Duff @ 2015-11-11 15:41 UTC (permalink / raw)


Serge Robyns <serge.robyns@gmail.com> writes:

> Hi Bob,
>
> On Wednesday, 11 November 2015 01:48:43 UTC+1, Bob Duff  wrote:
>> How about:
>> 
>>    function No_Client_Name return T_Client_Name is
>>       (T_Client_Name (P_Strings.Null_Bounded_String));
>
> May idea was to have a "constant" and use language construct/semantic to expose
> that.  I was expecting that the compiler will have more optimization options
> with such a construct than a dynamic construct like above.

I doubt that.  Especially if you put Inline.

>> But why do you need Preelaborate?  It's not all that much use if you use
>> GNAT's static elaboration model.
>
> Just for the sake of "cleanness" and again using language features to express
> my intent as per my "expectations".  Even if I would end up using GNAT in all
> cases.

One possibility is to use the option in GNAT that tells you where to put
pragma Elaborate_All, and put them in by hand.  Then you don't need
Preelaborate.

>> > Maybe I'm using bounded strings completely wrong.
>> 
>> Well, I think the Ada.Strings.Bounded package is way overengineered.
>> So "using Ada.Strings.Bounded" = "using bounded strings wrong".  ;-)
>> I suggest rolling your own.  No need for generics.
>> 
>>    type Bounded_String (Max_Length : Natural := ...) is limited record
>>       Length : Natural := 0;
>>       Chars  : String (1 .. Max_Length);
>>    end record;
>> 
>> along with a few trivial operations.
>
> I tend to agree that the bounded strings seems over-engineered but I'm lacking
> Ada experience to judge that properly.  However it is indeed a pain to use
> compared to other languages where I come from, e.g. C.  I don't know why
> strings are so complex to use in Ada. At various places I've conversions
> between bounded strings and plain strings in order to offer a consistent API to
> my modules. Luckily the package already provide a To_String function.  However,
> I've had to write loads of functions like "To_Client_Name (Name : in String)
> return T_Client_Name is (T_Client_Name (P_Strings.To_Bounded_String (Name));"
> as I haven't found a more direct way to convert a string to the type.

Can't you call the inherited To_Bounded_String directly?

>...This with
> some other oddities in Ada is what do give me a lot of frustrations.  However,
> I do remain decided to proceed with Ada, as I do believe in its core principles
> of allowing developing reliable software.
>
> Now with regards to rolling my own, is this not defeating re-use?  Why shall I
> waste my time on such a feature while I'm having loads of things to do on the
> application itself.

I'm all for reuse.  But in this case, the thing you're reusing causes a
fair amount of trouble, and rolling your own using the type I showed
above is trivial.

> I've been considering using unbounded strings instead but then I'm dropping the
> idea of a bounded storage for my entities.  Most of these "strings" ends up in
> record types which in the end will map to database entities.

Right, if you don't have a known bound, and you're not developing for a
small embedded system, then unbounded strings are often appropriate.
Those are complicated enough that I would not recommend rolling your
own.

Another alternative is Ada.Containers.Vectors instantiated with
Character.

- Bob


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

* Re: Bounded String question
  2015-11-11 14:32       ` brbarkstrom
@ 2015-11-11 16:08         ` Serge Robyns
  0 siblings, 0 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-11 16:08 UTC (permalink / raw)


On Wednesday, 11 November 2015 15:32:03 UTC+1, brbar...@gmail.com  wrote:
 
> Probably the sensible approach is not to expect Ada to act like C.  I use
> Bounded_Strings constantly and just expect to do the conversion from
> Bounded_Strings to plain String (and back).  It's a bit more verbose, but
> that may just be one of the costs of strong typing.

I'm not expecting Ada to act like C.  What I'm confused about is that in one case I use To_String (any type derived from the P_String package) from the P_String package but not To_Bounded_String.  Initially I wrote all the To_Strings myself but then the compiler warned me about not defining them as overriding.  I don't mind the verbosity, otherwise I could have stayed with C, java or why not even D on the contrary, this what attracted me to Ada.

> I'd also note that P_String seems to be rather close to the type name one
> would use in C for a pointer (or an access type in Ada).  Personally, I'd
> find that confusing.

I do agree, well I use T_xyz_Access for access types. It happens that my application's name start with a 'P' and at the same time I'm instating a package but I'll change this to something more expressive.

Serge

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

* Re: Bounded String question
  2015-11-11 13:43     ` Serge Robyns
  2015-11-11 14:32       ` brbarkstrom
@ 2015-11-11 17:27       ` Jeffrey R. Carter
  2015-11-11 20:06         ` Serge Robyns
  1 sibling, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-11 17:27 UTC (permalink / raw)


On 11/11/2015 06:43 AM, Serge Robyns wrote:
> On Wednesday, 11 November 2015 11:52:13 UTC+1, Serge Robyns  wrote:
>> I've had to write loads of functions like "To_Client_Name (Name : in
>> String) >return T_Client_Name is (T_Client_Name
>> (P_Strings.To_Bounded_String (Name));"

Only if you want a name other than To_Bounded_String.

> What does escape my understanding is why can I use To_String with any type
> defined from P_Strings but have to define all the To_xyz explicitly.  Is
> there a kind of "hidden" conversion applied in that case?

When you create a derived type, such as T_Client_Name, it inherits all the
primitive operations of its parent. In this case, that includes To_String and
To_Bounded_String. So you get functions

function To_String (S : T_Client_Name) return String;
function To_Bounded_String (S : String) return T_Client_Name;

Basically, all the operations in Generic_Bounded_Length that have a parameter or
return type of Bounded_String, with Bounded_String replaced by the name of the
derived type.

If you want something named To_T_Client_Name then of course you have to define
it yourself:

function To_T_Client_Name (S : String ) return T_Client_Name renames
To_Bounded_String;

The following compiles:

with Ada.Strings.Bounded;

procedure BS_Test is
   package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);

   type OS is new BS.Bounded_String;

   B : OS     := To_Bounded_String ("asdfghjkl");
   S : String := To_String (B);
begin -- BS_Test
   null;
end BS_Test;

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62

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

* Re: Bounded String question
  2015-11-11 15:34     ` Bob Duff
@ 2015-11-11 17:36       ` Jeffrey R. Carter
  2015-11-11 19:22         ` Bob Duff
  2016-03-06 18:59       ` Xavier Petit
  1 sibling, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-11 17:36 UTC (permalink / raw)


On 11/11/2015 08:34 AM, Bob Duff wrote:
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
> 
>> On 11/10/2015 05:48 PM, Bob Duff wrote:
>>>
>>> I suggest rolling your own.  No need for generics.
>>>
>>>    type Bounded_String (Max_Length : Natural := ...) is limited record
>>>       Length : Natural := 0;
>>>       Chars  : String (1 .. Max_Length);
>>>    end record;
>>
>> Except that using Natural for Max_Length results in GNAT allocating Integer'Last
>> characters for Chars, which is unlikely to fit on the stack.
> 
> No, the type is limited, so GNAT will allocate space for Max_Length
> characters, not Natural'Last characters.

I missed the "limited" and concentrated on the default for the discriminant. It
does mean that assignment becomes a bit messy, though.

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62

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

* Re: Bounded String question
  2015-11-11 17:36       ` Jeffrey R. Carter
@ 2015-11-11 19:22         ` Bob Duff
  0 siblings, 0 replies; 36+ messages in thread
From: Bob Duff @ 2015-11-11 19:22 UTC (permalink / raw)


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

> I missed the "limited" and concentrated on the default for the discriminant.

Right, for limited types, the default for a discriminant is just a
default, without the weird magical properties you get when its
nonlimited.

>...It
> does mean that assignment becomes a bit messy, though.

Yes, but I find that I hardly ever need assignment of these things.
They are used to build up a Bounded_String piece by piece, and
then do something with it (convert to String, convert to some
other type (like Name_Id, if you're familiar with compiler sources),
process in place...).

- Bob


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

* Re: Bounded String question
  2015-11-11 17:27       ` Jeffrey R. Carter
@ 2015-11-11 20:06         ` Serge Robyns
  2015-11-11 20:23           ` AdaMagica
  2015-11-11 20:42           ` Jeffrey R. Carter
  0 siblings, 2 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-11 20:06 UTC (permalink / raw)


I ended up using a per "type" bounded string instance.  This will anyway give me the most flexibility as each could have a different length in the final version.

package Client_Name_Strings is new Ada.Strings.Bounded.Generic_Bounded_Length (20);
subtype T_Client_Name is Client_Name_Strings.Bounded_String;
...
No_Client_Name : T_Client_Name renames Client_Name_Strings.Null_Bounded_String;
...
function To_Client_Name
  (Source : in String;
   Drop   : in Truncation := Error)
   return T_Client_Name
   renames Client_Name_Strings.To_Bounded_String;

I had to specify the full signature of To_Bounded_String, including default value to make it work with sub types.

With this construct the package also compiles and run with pragma preelaborate.
Moreover, "users" of the package will use types, constants and explicit functions and I can change the implementation at will.

On Wednesday, 11 November 2015 18:27:41 UTC+1, Jeffrey R. Carter  wrote:
> When you create a derived type, such as T_Client_Name, it inherits all the
> primitive operations of its parent. In this case, that includes To_String and
> To_Bounded_String. So you get functions
> 
> function To_String (S : T_Client_Name) return String;
> function To_Bounded_String (S : String) return T_Client_Name;
> 
> Basically, all the operations in Generic_Bounded_Length that have a parameter or
> return type of Bounded_String, with Bounded_String replaced by the name of the
> derived type.
> 
> If you want something named To_T_Client_Name then of course you have to define
> it yourself:
> 
> function To_T_Client_Name (S : String ) return T_Client_Name renames
> To_Bounded_String;
> 

I'm not sure this works, well not how I tried.

with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

procedure BS_Test is
   package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);

   type OS is new BS.Bounded_String;
   
   No_OS : OS renames BS.Null_Bounded_String;   
   function To_OS (Source : in String;
                  Drop : in Truncation := Error) return OS renames BS.To_Bounded_String;

   B : OS     := To_OS ("asdfghjkl");
   S : String := To_String (B);
begin -- BS_Test
   null;
end BS_Test;

gives

bs_test.adb:9:25: expected private type "OS" defined at line 7
bs_test.adb:9:25: found private type "Ada.Strings.Bounded.Bounded_String" from instance at line 5
bs_test.adb:10:04: no visible subprogram matches the specification for "To_OS"


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

* Re: Bounded String question
  2015-11-11 20:06         ` Serge Robyns
@ 2015-11-11 20:23           ` AdaMagica
  2015-11-11 20:27             ` AdaMagica
  2015-11-11 20:32             ` Serge Robyns
  2015-11-11 20:42           ` Jeffrey R. Carter
  1 sibling, 2 replies; 36+ messages in thread
From: AdaMagica @ 2015-11-11 20:23 UTC (permalink / raw)


This works:


with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

procedure BS_Test is
   package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);

   type OS is new BS.Bounded_String;
   
   No_OS : constant OS := OS (BS.Null_Bounded_String);  -- renaming does not work here, only allowed for tagged types

   function To_OS (Source : in String;
                  Drop : in Truncation := Error) return OS renames BS_Test.To_Bounded_String;  -- inherited operations are implicitly defined in the same declarative region as the derived type

   B : OS     := To_OS ("asdfghjkl");
   S : String := To_String (B);
begin -- BS_Test
   null;
end BS_Test; 


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

* Re: Bounded String question
  2015-11-11 20:23           ` AdaMagica
@ 2015-11-11 20:27             ` AdaMagica
  2015-11-11 20:32             ` Serge Robyns
  1 sibling, 0 replies; 36+ messages in thread
From: AdaMagica @ 2015-11-11 20:27 UTC (permalink / raw)


Am Mittwoch, 11. November 2015 21:23:58 UTC+1 schrieb AdaMagica:

>>    No_OS : constant OS := OS (BS.Null_Bounded_String);  -- renaming does not work here, only allowed for tagged types

Forgot to add: Constants are not inherited!

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

* Re: Bounded String question
  2015-11-11 20:23           ` AdaMagica
  2015-11-11 20:27             ` AdaMagica
@ 2015-11-11 20:32             ` Serge Robyns
  2015-11-11 20:40               ` AdaMagica
  1 sibling, 1 reply; 36+ messages in thread
From: Serge Robyns @ 2015-11-11 20:32 UTC (permalink / raw)


On Wednesday, 11 November 2015 21:23:58 UTC+1, AdaMagica  wrote:
> This works:
> 
> 
> with Ada.Strings; use Ada.Strings;
> with Ada.Strings.Bounded;
> 
> procedure BS_Test is
>    package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);
> 
>    type OS is new BS.Bounded_String;
>    
>    No_OS : constant OS := OS (BS.Null_Bounded_String);  -- renaming does not work here, only allowed for tagged types

This how this whole thread started.  That construct does not work with pragma preelaborate.  But this was exactly the code I had initially :-)


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

* Re: Bounded String question
  2015-11-11 20:32             ` Serge Robyns
@ 2015-11-11 20:40               ` AdaMagica
  2015-11-12 17:31                 ` Serge Robyns
  2015-11-12 18:03                 ` G.B.
  0 siblings, 2 replies; 36+ messages in thread
From: AdaMagica @ 2015-11-11 20:40 UTC (permalink / raw)


Am Mittwoch, 11. November 2015 21:32:39 UTC+1 schrieb Serge Robyns:
> This how this whole thread started.  That construct does not work
> with pragma preelaborate.  But this was exactly the code I had initially :-)

No complaint from GNAT GPL 2015:
--------------------------------

with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

procedure BS_Test is

  pragma Preelaborate;

  package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);

  type OS is new BS.Bounded_String;
   
  No_OS: constant OS := OS (BS.Null_Bounded_String);  -- renaming does not work here, only allowed for tagged types

  function To_OS (Source: in String;
                  Drop  : in Truncation := Error) return OS renames BS_Test.To_Bounded_String;  -- inherited operations are implicitly defined in the same declarative region as the derived type

   B: OS     := To_OS ("asdfghjkl");
   S: String := To_String (B);

begin -- BS_Test
   null;
end BS_Test; 

gprbuild -ws -c -f -u -PC:\Users\Grein\Documents\Christoph\Ada\Spielplatz\spielplatz.gpr -XGeneration=Ada_2012 bs_test.adb
gcc -c -gnato -g -fstack-check -gnata -gnatf -gnat12 bs_test.adb
[2015-11-11 21:37:27] process terminated successfully, elapsed time: 02.07s


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

* Re: Bounded String question
  2015-11-11 20:06         ` Serge Robyns
  2015-11-11 20:23           ` AdaMagica
@ 2015-11-11 20:42           ` Jeffrey R. Carter
  2015-11-12 16:59             ` Serge Robyns
  1 sibling, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-11 20:42 UTC (permalink / raw)


On 11/11/2015 01:06 PM, Serge Robyns wrote:
> 
> I had to specify the full signature of To_Bounded_String, including default value to make it work with sub types.

Sorry, I forgot the Drop parameter.

>    package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (20);
> 
>    type OS is new BS.Bounded_String;
>    
>    No_OS : OS renames BS.Null_Bounded_String;   
>    function To_OS (Source : in String;
>                   Drop : in Truncation := Error) return OS renames BS.To_Bounded_String;

These won't work. BS.Null_Bounded_String has type BS.Bounded_String, not OS.
However, you can convert BS.Null_Bounded_String

No_OS : constant OS := OS (BS.Null_Bounded_String);

or create your own

No_OS : constant OS := To_String ("");

Calling To_String requires elaboration.

Similarly, BS.To_Bounded_String returns BS.Bounded_String, not OS. However,
there is a directly visible To_Bounded_String that returns OS, and you can
rename that if you want:

function To_OS (Source : in String; Drop : in Truncation := Error)
return OS renames To_Bounded_String;

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62


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

* Re: Bounded String question
  2015-11-11 20:42           ` Jeffrey R. Carter
@ 2015-11-12 16:59             ` Serge Robyns
  2015-11-12 18:39               ` Jeffrey R. Carter
  2015-11-12 21:27               ` Randy Brukardt
  0 siblings, 2 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-12 16:59 UTC (permalink / raw)


On Wednesday, 11 November 2015 21:42:58 UTC+1, Jeffrey R. Carter  wrote:
> Sorry, I forgot the Drop parameter.

Don't worry, this was very easy to resolve.  I wish all my issues where that easy. ;-)

> These won't work. BS.Null_Bounded_String has type BS.Bounded_String, not OS.
> However, you can convert BS.Null_Bounded_String
> 
> No_OS : constant OS := OS (BS.Null_Bounded_String);
> 
> or create your own
> 
> No_OS : constant OS := To_String ("");

I had both these version in my code (started with To_xyz ("") and then Null_Bounded_String, as the later form is the one I like.  My quest started when I introduced pragma preelaborate.  I started digging into the details without becoming any smarter, on the contrary.  And asked my question here.

> Calling To_String requires elaboration.

I was foolishly hoping that these kind of elaborations could be preelaborated.  But the RM says not and the compiler slaps me.  After working around as mentioned earlier in my discussions I was hit by another slap but this time trying to preelaborate "simple" record types with my constants.  So in the end, I throw the towel and leave it up to the compiler to figure out how to elaborate my code.  So far my attempt to hint and to have nice pure or preelaborated packages.  I'm left with a "hangover". 


> -- 
> Jeff Carter
> "When Roman engineers built a bridge, they had to stand under it
> while the first legion marched across. If programmers today
> worked under similar ground rules, they might well find
> themselves getting much more interested in Ada!"
> Robert Dewar
> 62

From your post, I do understand you are an authority when it comes to language rules.  Am I so mistaken to hope that today's compilers could be smarter in preelaboration besides plain strings and scalars?  Is this something that could be looked at in the next Ada revision?

Serge

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

* Re: Bounded String question
  2015-11-11 20:40               ` AdaMagica
@ 2015-11-12 17:31                 ` Serge Robyns
  2015-11-12 19:10                   ` AdaMagica
  2015-11-12 18:03                 ` G.B.
  1 sibling, 1 reply; 36+ messages in thread
From: Serge Robyns @ 2015-11-12 17:31 UTC (permalink / raw)


On Wednesday, 11 November 2015 21:40:35 UTC+1, AdaMagica  wrote:

> No complaint from GNAT GPL 2015:
> --------------------------------
> 

> gprbuild -ws -c -f -u -PC:\Users\Grein\Documents\Christoph\Ada\Spielplatz\spielplatz.gpr -XGeneration=Ada_2012 bs_test.adb
> gcc -c -gnato -g -fstack-check -gnata -gnatf -gnat12 bs_test.adb
> [2015-11-11 21:37:27] process terminated successfully, elapsed time: 02.07s

I'm baffled.  I copied you code and indeed.  I added Put_Line just to make sure there is something in the body and to see the output :-P.

When applying this again on my package I get my previous errors.  I tried to moved up my private declarations of the constants into the visible part, no relieve.  I moved the constant declaration right after the type declaration no solution neither.  The error message is very clear and I can't disagree with them:
: non-static constant in preelaborated unit
: static expression must have scalar or string type (RM 4.9(2))

I've noticed that error messages can change because of other errors.  I had that on certain occasions.  Maybe, as in some other cases, the compiler just missed to moan in your example but do actually fail with respect to the standards.

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

* Re: Bounded String question
  2015-11-11 20:40               ` AdaMagica
  2015-11-12 17:31                 ` Serge Robyns
@ 2015-11-12 18:03                 ` G.B.
  2015-11-12 18:13                   ` Serge Robyns
  2015-11-12 19:37                   ` Randy Brukardt
  1 sibling, 2 replies; 36+ messages in thread
From: G.B. @ 2015-11-12 18:03 UTC (permalink / raw)


On 11.11.15 21:40, AdaMagica wrote:
> Am Mittwoch, 11. November 2015 21:32:39 UTC+1 schrieb Serge Robyns:
>> This how this whole thread started.  That construct does not work
>> with pragma preelaborate.  But this was exactly the code I had initially :-)
>
> No complaint from GNAT GPL 2015:
> --------------------------------
>
> with Ada.Strings; use Ada.Strings;
> with Ada.Strings.Bounded;
>
> procedure BS_Test is
>
>    pragma Preelaborate;

Are the requirements for Elaborate (or for Pure) different for
a library unit that is a subprogram? GNAT does not rejected this
"pure" one either:

procedure Purity (A : Integer) is

    pragma Pure (Purity);

    type P is access String;

    X : P := new String'("abc");
    Y : String := Integer'Image (A);
    Z : String := Y (1) & Y (A);

begin
    Y (3) := X (1);
end Purity;

Diagnostics change in the opposite direction when the same declarations
appear in a package spec.

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

* Re: Bounded String question
  2015-11-12 18:03                 ` G.B.
@ 2015-11-12 18:13                   ` Serge Robyns
  2015-11-12 18:14                     ` Serge Robyns
  2015-11-12 19:37                   ` Randy Brukardt
  1 sibling, 1 reply; 36+ messages in thread
From: Serge Robyns @ 2015-11-12 18:13 UTC (permalink / raw)


On Thursday, 12 November 2015 19:03:19 UTC+1, G.B.  wrote:
> On 11.11.15 21:40, AdaMagica wrote:
> > Am Mittwoch, 11. November 2015 21:32:39 UTC+1 schrieb Serge Robyns:
> >> This how this whole thread started.  That construct does not work
> >> with pragma preelaborate.  But this was exactly the code I had initially :-)
> >
> > No complaint from GNAT GPL 2015:
> > --------------------------------
> >
> > with Ada.Strings; use Ada.Strings;
> > with Ada.Strings.Bounded;
> >
> > procedure BS_Test is
> >
> >    pragma Preelaborate;
> 
> Are the requirements for Elaborate (or for Pure) different for
> a library unit that is a subprogram? GNAT does not rejected this
> "pure" one either:
> 
> procedure Purity (A : Integer) is
> 
>     pragma Pure (Purity);
> 
>     type P is access String;
> 
>     X : P := new String'("abc");
>     Y : String := Integer'Image (A);
>     Z : String := Y (1) & Y (A);
> 
> begin
>     Y (3) := X (1);
> end Purity;
> 
> Diagnostics change in the opposite direction when the same declarations
> appear in a package spec.

I do confirm the exact diagnostic.


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

* Re: Bounded String question
  2015-11-12 18:13                   ` Serge Robyns
@ 2015-11-12 18:14                     ` Serge Robyns
  0 siblings, 0 replies; 36+ messages in thread
From: Serge Robyns @ 2015-11-12 18:14 UTC (permalink / raw)


On Thursday, 12 November 2015 19:13:17 UTC+1, Serge Robyns  wrote:
> On Thursday, 12 November 2015 19:03:19 UTC+1, G.B.  wrote:
> > On 11.11.15 21:40, AdaMagica wrote:
> > > Am Mittwoch, 11. November 2015 21:32:39 UTC+1 schrieb Serge Robyns:
> > >> This how this whole thread started.  That construct does not work
> > >> with pragma preelaborate.  But this was exactly the code I had initially :-)
> > >
> > > No complaint from GNAT GPL 2015:
> > > --------------------------------
> > >
> > > with Ada.Strings; use Ada.Strings;
> > > with Ada.Strings.Bounded;
> > >
> > > procedure BS_Test is
> > >
> > >    pragma Preelaborate;
> > 
> > Are the requirements for Elaborate (or for Pure) different for
> > a library unit that is a subprogram? GNAT does not rejected this
> > "pure" one either:
> > 
> > procedure Purity (A : Integer) is
> > 
> >     pragma Pure (Purity);
> > 
> >     type P is access String;
> > 
> >     X : P := new String'("abc");
> >     Y : String := Integer'Image (A);
> >     Z : String := Y (1) & Y (A);
> > 
> > begin
> >     Y (3) := X (1);
> > end Purity;
> > 
> > Diagnostics change in the opposite direction when the same declarations
> > appear in a package spec.
> 
> I do confirm the exact diagnostic.

The exact same diagnostic to complete my initial statement.

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

* Re: Bounded String question
  2015-11-12 16:59             ` Serge Robyns
@ 2015-11-12 18:39               ` Jeffrey R. Carter
  2015-11-12 21:19                 ` Randy Brukardt
  2015-11-12 21:27               ` Randy Brukardt
  1 sibling, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-12 18:39 UTC (permalink / raw)


On 11/12/2015 09:59 AM, Serge Robyns wrote:
> 
> From your post, I do understand you are an authority when it comes to
> language rules.  Am I so mistaken to hope that today's compilers could be
> smarter in preelaboration besides plain strings and scalars?  Is this
> something that could be looked at in the next Ada revision?

I'm not nearly as much of an authority as Bob Duff, who has commented on this
thread, or the other ARG members ("language lawyers" in common parlance) who
post here. The ARM tries to not limit implementation approaches and to stick to
things that compiler writers know how to do. The latter tends to grow with time,
so one can always hope for the list of pre-elaborable constructs to grow.
However, Null_Bounded_String is a deferred constant of a private type, so I
wouldn't hold my breath.

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail
02

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

* Re: Bounded String question
  2015-11-12 17:31                 ` Serge Robyns
@ 2015-11-12 19:10                   ` AdaMagica
  2015-11-12 21:29                     ` Randy Brukardt
  0 siblings, 1 reply; 36+ messages in thread
From: AdaMagica @ 2015-11-12 19:10 UTC (permalink / raw)


Am Donnerstag, 12. November 2015 18:31:18 UTC+1 schrieb Serge Robyns:
> I'm baffled.  I copied you code and indeed.

Looks like a bug in GNAT GPL 2015 (with a procedure). When I change the procedure to a package, I get the same complaint.

I habe to admit, I was too lazy to look up the conditions on Preelaborate.


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

* Re: Bounded String question
  2015-11-12 18:03                 ` G.B.
  2015-11-12 18:13                   ` Serge Robyns
@ 2015-11-12 19:37                   ` Randy Brukardt
  1 sibling, 0 replies; 36+ messages in thread
From: Randy Brukardt @ 2015-11-12 19:37 UTC (permalink / raw)


"G.B." <bauhaus@futureapps.invalid> wrote in message 
news:n22k4s$vk3$1@dont-email.me...
> On 11.11.15 21:40, AdaMagica wrote:
>> Am Mittwoch, 11. November 2015 21:32:39 UTC+1 schrieb Serge Robyns:
>>> This how this whole thread started.  That construct does not work
>>> with pragma preelaborate.  But this was exactly the code I had initially 
>>> :-)
>>
>> No complaint from GNAT GPL 2015:
>> --------------------------------
>>
>> with Ada.Strings; use Ada.Strings;
>> with Ada.Strings.Bounded;
>>
>> procedure BS_Test is
>>
>>    pragma Preelaborate;
>
> Are the requirements for Elaborate (or for Pure) different for
> a library unit that is a subprogram?

Yes. The Preelaborate rules only apply at library level, and a procedure is 
not library level by definition.

One cannot declare a preelaborable bounded string constant, as the 
initialization will necessarily fail the preelaboration checks.

I recently worked out a proposal that could have changed that, but it became 
way too complex and it went nowhere. (Recall the similar discussion here 
about having a preelaborable constant of type Address.)

                                         Randy.


                     Randy.


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

* Re: Bounded String question
  2015-11-12 18:39               ` Jeffrey R. Carter
@ 2015-11-12 21:19                 ` Randy Brukardt
  0 siblings, 0 replies; 36+ messages in thread
From: Randy Brukardt @ 2015-11-12 21:19 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:n22m8h$92u$1@dont-email.me...
> On 11/12/2015 09:59 AM, Serge Robyns wrote:
>>
>> From your post, I do understand you are an authority when it comes to
>> language rules.  Am I so mistaken to hope that today's compilers could be
>> smarter in preelaboration besides plain strings and scalars?  Is this
>> something that could be looked at in the next Ada revision?
>
> I'm not nearly as much of an authority as Bob Duff, who has commented on 
> this
> thread, or the other ARG members ("language lawyers" in common parlance) 
> who
> post here. The ARM tries to not limit implementation approaches and to 
> stick to
> things that compiler writers know how to do. The latter tends to grow with 
> time,
> so one can always hope for the list of pre-elaborable constructs to grow.
> However, Null_Bounded_String is a deferred constant of a private type, so 
> I
> wouldn't hold my breath.

See the now dead AI12-0175-1/01 for how it could (relatively) easily be 
accomplished. But that's considered to be too much mechanism, and it won't 
go anywhere.

                                         Randy.



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

* Re: Bounded String question
  2015-11-12 16:59             ` Serge Robyns
  2015-11-12 18:39               ` Jeffrey R. Carter
@ 2015-11-12 21:27               ` Randy Brukardt
  2015-11-12 22:32                 ` Jeffrey R. Carter
  1 sibling, 1 reply; 36+ messages in thread
From: Randy Brukardt @ 2015-11-12 21:27 UTC (permalink / raw)


"Serge Robyns" <serge.robyns@gmail.com> wrote in message 
news:272d6ba6-869f-427d-9395-51dd1d480a3c@googlegroups.com...
...
> Am I so mistaken to hope that today's compilers could be smarter in 
> preelaboration
> besides plain strings and scalars?  Is this something that could be looked 
> at in the
> next Ada revision?

We already did, at our last meeting (AI12-0175-1/01), and it was soundly 
rejected as too complicated for the problem being solved. (As the author of 
the proposal, it was hard to disagree; I had expected the solution to be 
simpler than it worked out -- but the main problem is the inconsistency of 
the existing staticness rules (lots of things that should be allowed for 
static strings are not allowed, and fixing that makes the proposal feel 
heavy even if it isn't really).

I'd be surprised if we revisited it. The main problem being that Pure and 
Preelaborated units are far less useful than originally thought. (I've never 
successfully made any of my packages Pure or Preelaborated). It's unclear 
whether it is worth spending effort on what is essentially a failed feature. 
(We do anyway, but I doubt that we'd do anything major, especially as Pure 
is tangled up in the Annex E features - most relaxations cause problems for 
Annex E.)

                                    Randy.





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

* Re: Bounded String question
  2015-11-12 19:10                   ` AdaMagica
@ 2015-11-12 21:29                     ` Randy Brukardt
  0 siblings, 0 replies; 36+ messages in thread
From: Randy Brukardt @ 2015-11-12 21:29 UTC (permalink / raw)



"AdaMagica" <christ-usch.grein@t-online.de> wrote in message 
news:62d6cec4-14b9-4d5c-b3bd-ccd7c9ea410d@googlegroups.com...
> Am Donnerstag, 12. November 2015 18:31:18 UTC+1 schrieb Serge Robyns:
>> I'm baffled.  I copied you code and indeed.
>
> Looks like a bug in GNAT GPL 2015 (with a procedure). When I change the 
> procedure to a package, I get the same complaint.
>
> I habe to admit, I was too lazy to look up the conditions on Preelaborate.

No bug here; preelaboration has no effect on a procedure -- which should be 
obvious as elaborating a procedure itself has no effect other than 
eliminating Program_Error when it is called. It's the elaboration of 
library-level objects that is problematical and has all of the rules.

                      Randy.



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

* Re: Bounded String question
  2015-11-12 21:27               ` Randy Brukardt
@ 2015-11-12 22:32                 ` Jeffrey R. Carter
  2015-11-13  0:07                   ` Randy Brukardt
  0 siblings, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-12 22:32 UTC (permalink / raw)


On 11/12/2015 02:27 PM, Randy Brukardt wrote:
> 
> We already did, at our last meeting (AI12-0175-1/01), and it was soundly 
> rejected as too complicated for the problem being solved. (As the author of 
> the proposal, it was hard to disagree; I had expected the solution to be 
> simpler than it worked out -- but the main problem is the inconsistency of 
> the existing staticness rules (lots of things that should be allowed for 
> static strings are not allowed, and fixing that makes the proposal feel 
> heavy even if it isn't really).

How about just cleaning up the existing rules on what is static? That seems
worthwhile in itself. If that's done, perhaps then expanding the things that are
pre-elaborable would be acceptably complicated.

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail
02

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

* Re: Bounded String question
  2015-11-12 22:32                 ` Jeffrey R. Carter
@ 2015-11-13  0:07                   ` Randy Brukardt
  2015-11-13  1:01                     ` Jeffrey R. Carter
  0 siblings, 1 reply; 36+ messages in thread
From: Randy Brukardt @ 2015-11-13  0:07 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:n233te$1h5$1@dont-email.me...
> On 11/12/2015 02:27 PM, Randy Brukardt wrote:
>>
>> We already did, at our last meeting (AI12-0175-1/01), and it was soundly
>> rejected as too complicated for the problem being solved. (As the author 
>> of
>> the proposal, it was hard to disagree; I had expected the solution to be
>> simpler than it worked out -- but the main problem is the inconsistency 
>> of
>> the existing staticness rules (lots of things that should be allowed for
>> static strings are not allowed, and fixing that makes the proposal feel
>> heavy even if it isn't really).
>
> How about just cleaning up the existing rules on what is static? That 
> seems
> worthwhile in itself. If that's done, perhaps then expanding the things 
> that are
> pre-elaborable would be acceptably complicated.

That's essentially what I proposed (with aspects to allow private types to 
be potentially static requiring the full type to be potentially static). 
Without the private type mechanism, it isn't worth much (both Address and 
Bounded_String are private, after all, and so are most user-defined types as 
Ada programmers tend to take the ADT idea seriously). But it just got too 
complicated. Without that, you just get discrete and string types as static, 
and there isn't much to change with those.

                                           Randy.




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

* Re: Bounded String question
  2015-11-13  0:07                   ` Randy Brukardt
@ 2015-11-13  1:01                     ` Jeffrey R. Carter
  0 siblings, 0 replies; 36+ messages in thread
From: Jeffrey R. Carter @ 2015-11-13  1:01 UTC (permalink / raw)


If anyone's interested, there's now a bounded-string pkg in the PragmAda
Reusable Components for ISO/IEC 8652:2007, based on Duff's suggestion here. It's
pretty much untested, but feel free to play with it.

https://pragmada.x10hosting.com/pragmarc.htm

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail
02


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

* Re: Bounded String question
  2015-11-11 15:34     ` Bob Duff
  2015-11-11 17:36       ` Jeffrey R. Carter
@ 2016-03-06 18:59       ` Xavier Petit
  2016-03-07 23:16         ` Randy Brukardt
  1 sibling, 1 reply; 36+ messages in thread
From: Xavier Petit @ 2016-03-06 18:59 UTC (permalink / raw)


Le 11/11/2015 16:34, Bob Duff a écrit :
> No, the type is limited, so GNAT will allocate space for Max_Length
> characters, not Natural'Last characters.
>
> - Bob
>

Hello, I have noticed a problem with this technique, and I would like
to know if it is normal or a GNAT problem. With this source code =>

procedure Test_Bounded_String is
    package Bounded_String is
       type T (Max_Length : Natural := 100) is limited private;

    private
       type T (Max_Length : Natural := 100) is limited record
	 Length : Natural := 0;
	 Chars  : String (1 .. Max_Length);
       end record;
    end Bounded_String;

    Test : Bounded_String.T;

begin
    null;
end Test_Bounded_String;

$ gnatmake test_bounded_string.adb
gcc-5 -c test_bounded_string.adb
test_bounded_string.adb:12:04: warning: variable "Test" is never read
and never assigned
gnatbind-5 -x test_bounded_string.ali
gnatlink-5 test_bounded_string.ali
$ ./test_bounded_string

raised STORAGE_ERROR : stack overflow or erroneous memory access


But, if the type "T" is publicly fully declared, then all goes well :

    package Bounded_String is
       type T (Max_Length : Natural := 100) is limited record
	 Length : Natural := 0;
	 Chars  : String (1 .. Max_Length);
       end record;
    end Bounded_String;


$ gnatmake --version
GNATMAKE 5.3.1

$ cat /etc/debian_version
stretch/sid

$ apt-cache show gnat-5
Package: gnat-5
Source: gcc-5
Version: 5.3.1-8

$ cat /proc/version
Linux version 4.3.0-1-amd64 (debian-kernel@lists.debian.org) (gcc
version 5.3.1 20160121 (Debian 5.3.1-7) ) #1 SMP Debian 4.3.5-1 (2016-02-06)

The problem also occurs with GNAT 4.9.2 from Debian stable.
Thanks by advance !

-- 
Xavier Petit


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

* Re: Bounded String question
  2016-03-06 18:59       ` Xavier Petit
@ 2016-03-07 23:16         ` Randy Brukardt
  2016-03-08  0:08           ` Jeffrey R. Carter
  0 siblings, 1 reply; 36+ messages in thread
From: Randy Brukardt @ 2016-03-07 23:16 UTC (permalink / raw)


"Xavier Petit" <xpetit@becoast.fr> wrote in message 
news:56dc7e22$0$19749$426a34cc@news.free.fr...

I don't know if this is relevant...

> procedure Test_Bounded_String is
>    package Bounded_String is
>       type T (Max_Length : Natural := 100) is limited private;

...but a type like this can be completed with a non-limited type. That might 
prevent the compiler from applying a limited-only optimization. (Another way 
to say it is that this type is not inherently limited; non-limited views can 
exist of such types, and a non-limited view would need an allocate-the-max 
strategy [or a non-contiguous object].)

You might try making this type tagged, as that would make it inherently 
limited and *might* allow the compiler to make the optimization. (Or it 
simply might not work for any private type - optimizations are just that, 
and it isn't always easy to apply them to partial views.) Otherwise, you'll 
have to forgo using a private type (ugh, I know).

                                   Randy.



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

* Re: Bounded String question
  2016-03-07 23:16         ` Randy Brukardt
@ 2016-03-08  0:08           ` Jeffrey R. Carter
  2016-03-09  1:18             ` Randy Brukardt
  0 siblings, 1 reply; 36+ messages in thread
From: Jeffrey R. Carter @ 2016-03-08  0:08 UTC (permalink / raw)


On 03/07/2016 04:16 PM, Randy Brukardt wrote:
> "Xavier Petit" <xpetit@becoast.fr> wrote in message 
> news:56dc7e22$0$19749$426a34cc@news.free.fr...
> 
> I don't know if this is relevant...
> 
>> procedure Test_Bounded_String is
>>    package Bounded_String is
>>       type T (Max_Length : Natural := 100) is limited private;
> 
> ...but a type like this can be completed with a non-limited type. That might 
> prevent the compiler from applying a limited-only optimization. (Another way 
> to say it is that this type is not inherently limited; non-limited views can 
> exist of such types, and a non-limited view would need an allocate-the-max 
> strategy [or a non-contiguous object].)

The compiler knows the full type (which is limited) when it compiles the
variable declaration and its associated elaboration code. Would it not be able
to use that information?

> You might try making this type tagged, as that would make it inherently 
> limited and *might* allow the compiler to make the optimization. (Or it 
> simply might not work for any private type - optimizations are just that, 
> and it isn't always easy to apply them to partial views.) Otherwise, you'll 
> have to forgo using a private type (ugh, I know).

My first reaction was that one can't have default discriminants for a tagged
type. I see Ada-12 removed the rule against tagged types having default
discriminants, prohibiting them only for non-limited tagged types. I try not to
write code for languages with only a single compiler provider, so I still tend
to adhere to the earlier rule.

You can also remove the default and add a subtype with the discriminant specified.

type Base_T (Max_Length : Natural) is [limited] private; -- limited no longer needed

subtype T is Base_T (Max_Length => 100);

though that's somewhat less convenient.

-- 
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] 36+ messages in thread

* Re: Bounded String question
  2016-03-08  0:08           ` Jeffrey R. Carter
@ 2016-03-09  1:18             ` Randy Brukardt
  0 siblings, 0 replies; 36+ messages in thread
From: Randy Brukardt @ 2016-03-09  1:18 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:nbl50v$8qq$1@dont-email.me...
> On 03/07/2016 04:16 PM, Randy Brukardt wrote:
>> "Xavier Petit" <xpetit@becoast.fr> wrote in message
>> news:56dc7e22$0$19749$426a34cc@news.free.fr...
>>
>> I don't know if this is relevant...
>>
>>> procedure Test_Bounded_String is
>>>    package Bounded_String is
>>>       type T (Max_Length : Natural := 100) is limited private;
>>
>> ...but a type like this can be completed with a non-limited type. That 
>> might
>> prevent the compiler from applying a limited-only optimization. (Another 
>> way
>> to say it is that this type is not inherently limited; non-limited views 
>> can
>> exist of such types, and a non-limited view would need an 
>> allocate-the-max
>> strategy [or a non-contiguous object].)
>
> The compiler knows the full type (which is limited) when it compiles the
> variable declaration and its associated elaboration code. Would it not be 
> able
> to use that information?

I'd be speculating to say anything about someone else's compiler. (One thing 
that we've all learned from the ARG is that what seems natural to one 
compiler implementer can require some amazingly twisted implementation in 
some other compiler. Best to never assume anything about some other 
compiler.)

But I will say that it would depend on how the compiler handles objects. For 
Janus/Ada, it is the type, not the object, that determines the memory 
management strategy, so we have to tie that down fairly early.

And, in any case, the presence of a partial view subtly changes the 
semantics of a type. (That's was added in Ada 2005 because the Ada 95 rule 
had the unpleasant effect of making the details of the full type relevant to 
the usage of the objects in some cases. It's rather a rather messy rule but 
it was added to preserve the notion that all you need to know about is the 
private type. (In Ada 95, you could get Constraint_Error when assigning two 
objects of a type with no visible discriminants. Yuck.) So those rules as 
well might cause a problem.

                                   Randy.



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

end of thread, other threads:[~2016-03-09  1:18 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-10 22:00 Bounded String question Serge Robyns
2015-11-11  0:48 ` Bob Duff
2015-11-11  2:01   ` Jeffrey R. Carter
2015-11-11 15:34     ` Bob Duff
2015-11-11 17:36       ` Jeffrey R. Carter
2015-11-11 19:22         ` Bob Duff
2016-03-06 18:59       ` Xavier Petit
2016-03-07 23:16         ` Randy Brukardt
2016-03-08  0:08           ` Jeffrey R. Carter
2016-03-09  1:18             ` Randy Brukardt
2015-11-11 10:52   ` Serge Robyns
2015-11-11 13:43     ` Serge Robyns
2015-11-11 14:32       ` brbarkstrom
2015-11-11 16:08         ` Serge Robyns
2015-11-11 17:27       ` Jeffrey R. Carter
2015-11-11 20:06         ` Serge Robyns
2015-11-11 20:23           ` AdaMagica
2015-11-11 20:27             ` AdaMagica
2015-11-11 20:32             ` Serge Robyns
2015-11-11 20:40               ` AdaMagica
2015-11-12 17:31                 ` Serge Robyns
2015-11-12 19:10                   ` AdaMagica
2015-11-12 21:29                     ` Randy Brukardt
2015-11-12 18:03                 ` G.B.
2015-11-12 18:13                   ` Serge Robyns
2015-11-12 18:14                     ` Serge Robyns
2015-11-12 19:37                   ` Randy Brukardt
2015-11-11 20:42           ` Jeffrey R. Carter
2015-11-12 16:59             ` Serge Robyns
2015-11-12 18:39               ` Jeffrey R. Carter
2015-11-12 21:19                 ` Randy Brukardt
2015-11-12 21:27               ` Randy Brukardt
2015-11-12 22:32                 ` Jeffrey R. Carter
2015-11-13  0:07                   ` Randy Brukardt
2015-11-13  1:01                     ` Jeffrey R. Carter
2015-11-11 15:41     ` Bob Duff

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