comp.lang.ada
 help / color / mirror / Atom feed
* Empty String confusion; Positive and Natural
@ 2021-11-29 17:34 Kevin Chadwick
  2021-11-29 18:05 ` Jeffrey R.Carter
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Kevin Chadwick @ 2021-11-29 17:34 UTC (permalink / raw)


I suspect that I am doing something outside of Ada norms.

Are empty strings avoided in Ada?

I have a function to create a record containing strings amongst other things like a subtyped integer, simply to group the outputs neatly of another function.

If something goes wrong and I run the create function with "" then the strings length is zero. Why is a string type Positive and not Natural, because empty strings are in fact useless?

I guess I shall consider re-engineering my functions, rather than add checks, but all thoughts are welcome.

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 17:34 Empty String confusion; Positive and Natural Kevin Chadwick
@ 2021-11-29 18:05 ` Jeffrey R.Carter
  2021-11-29 19:19 ` Niklas Holsti
  2021-11-30  7:40 ` ldries46
  2 siblings, 0 replies; 13+ messages in thread
From: Jeffrey R.Carter @ 2021-11-29 18:05 UTC (permalink / raw)


On 2021-11-29 18:34, Kevin Chadwick wrote:
> 
> If something goes wrong and I run the create function with "" then the strings length is zero. Why is a string type Positive and not Natural, because empty strings are in fact useless?

I don't understand what you're asking. 'Length returns 
universal_integer; it is independent of the index subtype. The index 
subtype can even be non-numeric.

-- 
Jeff Carter
Programming by extension, emphasizing, as it does,
ease of writing over ease of reading, should be
avoided whenever possible by S/W engineers, and
used with the same reluctance and care that they
give to gotos and access types.
175

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 17:34 Empty String confusion; Positive and Natural Kevin Chadwick
  2021-11-29 18:05 ` Jeffrey R.Carter
@ 2021-11-29 19:19 ` Niklas Holsti
  2021-11-29 22:50   ` Kevin Chadwick
  2021-11-30  7:40 ` ldries46
  2 siblings, 1 reply; 13+ messages in thread
From: Niklas Holsti @ 2021-11-29 19:19 UTC (permalink / raw)


On 2021-11-29 19:34, Kevin Chadwick wrote:
> I suspect that I am doing something outside of Ada norms.
> 
> Are empty strings avoided in Ada?


No, empty strings (and empty arrays in general) are quite usable.


> I have a function to create a record containing strings amongst other
> things like a subtyped integer, simply to group the outputs neatly of
> another function.


It would clarify your question if you would show the declaration of that 
record type. Does it use the String type, or the Unbounded_String type?


> If something goes wrong and I run the create function with "" then
> the strings length is zero.


Is there something wrong with that? An empty string should have length 
zero, it seems to me.


> Why is a string type Positive and not Natural, because empty strings
> are in fact useless?

An object S : String is an empty string if and only if S'Length = 0. 
(And, as Jeff said, S'Length is not a Positive, but a universal integer, 
so it can be zero even if Strings are indexed with Positive numbers.)

Also, an object S : String is an empty string if and only if S'Last < 
S'First. Note that S'Last can be much less than S'First, so in this case 
you cannot compute the length of the string from S'Last - S'First + 1. 
Or if you do, you can get a negative result, and understand that as zero 
length.

The case where S'Last is much less than S'First usually comes about when 
one takes an empty slice of an existing string, for example X(5 .. 2), 
where X is for example String (1 .. 10).

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 19:19 ` Niklas Holsti
@ 2021-11-29 22:50   ` Kevin Chadwick
  2021-11-30  8:29     ` Simon Wright
                       ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Kevin Chadwick @ 2021-11-29 22:50 UTC (permalink / raw)


> It would clarify your question if you would show the declaration of that 
> record type. Does it use the String type, or the Unbounded_String type?

Hopefully I will have a doh moment when I get into the office in the morning and post code. I am getting a range check exception when I assign "" to a standard.String in a record by returning the record from a function. Surely, I must have caused it somehow.

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 17:34 Empty String confusion; Positive and Natural Kevin Chadwick
  2021-11-29 18:05 ` Jeffrey R.Carter
  2021-11-29 19:19 ` Niklas Holsti
@ 2021-11-30  7:40 ` ldries46
  2021-11-30  8:21   ` Simon Wright
  2 siblings, 1 reply; 13+ messages in thread
From: ldries46 @ 2021-11-30  7:40 UTC (permalink / raw)


Op 29-11-2021 om 18:34 schreef Kevin Chadwick:
> I suspect that I am doing something outside of Ada norms.
>
> Are empty strings avoided in Ada?
>
> I have a function to create a record containing strings amongst other things like a subtyped integer, simply to group the outputs neatly of another function.
>
> If something goes wrong and I run the create function with "" then the strings length is zero. Why is a string type Positive and not Natural, because empty strings are in fact useless?
>
> I guess I shall consider re-engineering my functions, rather than add checks, but all thoughts are welcome.
 From your description, I suspect that you are using different 
declarations for the strings you use for instance while " " in fact is a 
string(1.1) you try to put this in a string(1 .. 5).
To avoid this kind of problems I generally use the package 
Ada.Strings.Unbounded where have possibilities to operate strings 
without caring for the length. Changing between strings and unbounded 
strings is possible with functions in the package.
I would then advice you to create an variable at a position where it is 
reachable from all packages where you use it:
Empty_String : Unbounded_String := To_Unbounded_String("");

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

* Re: Empty String confusion; Positive and Natural
  2021-11-30  7:40 ` ldries46
@ 2021-11-30  8:21   ` Simon Wright
  2021-11-30 12:39     ` ldries46
  0 siblings, 1 reply; 13+ messages in thread
From: Simon Wright @ 2021-11-30  8:21 UTC (permalink / raw)


ldries46 <bertus.dries@planet.nl> writes:

> Empty_String : Unbounded_String := To_Unbounded_String("");

* Given the name, you should probably declare it constant.

* You don't need to initialize it, ARM 4.5(73) [1] says "If an object of
  type Unbounded_String is not otherwise initialized, it will be
  initialized to the same value as Null_Unbounded_String".

* Ada.Strings.Unbounded.Null_Unbounded_String is a constant empty
  string.

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-4-5.html#p73

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 22:50   ` Kevin Chadwick
@ 2021-11-30  8:29     ` Simon Wright
  2021-11-30  8:34     ` Niklas Holsti
  2021-11-30 10:00     ` Jeffrey R.Carter
  2 siblings, 0 replies; 13+ messages in thread
From: Simon Wright @ 2021-11-30  8:29 UTC (permalink / raw)


Kevin Chadwick <kevc3no4@gmail.com> writes:

>> It would clarify your question if you would show the declaration of
>> that record type. Does it use the String type, or the
>> Unbounded_String type?
>
> Hopefully I will have a doh moment when I get into the office in the
> morning and post code. I am getting a range check exception when I
> assign "" to a standard.String in a record by returning the record
> from a function. Surely, I must have caused it somehow.

If you declare S : String (1 .. 5) and you want to assign a string "foo"
to the whole of S you are forbidden to do so by the language: you have
to assign 5 characters, no more, no fewer.

This can be a royal pain, so we have Ada.Strings.Bounded (if you know
the maximum length) or .Unbounded (if you don't, and can afford more
overhead), both of which support variable-length strings.

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 22:50   ` Kevin Chadwick
  2021-11-30  8:29     ` Simon Wright
@ 2021-11-30  8:34     ` Niklas Holsti
  2021-11-30 10:00     ` Jeffrey R.Carter
  2 siblings, 0 replies; 13+ messages in thread
From: Niklas Holsti @ 2021-11-30  8:34 UTC (permalink / raw)


On 2021-11-30 0:50, Kevin Chadwick wrote:
>> It would clarify your question if you would show the declaration of that
>> record type. Does it use the String type, or the Unbounded_String type?
> 
> Hopefully I will have a doh moment when I get into the office in the
> morning and post code. I am getting a range check exception when I
> assign "" to a standard.String

Although Standard.String is an unconstrained array type (that is, its 
index range is defined as "Positive range <>"), every object of this 
type is constrained to a fixed length, set when the object is created.

So if you have, for example:

    S : String (1 .. 10);

then S'Length is always 10. If you try to assign to S a string of a 
different length, for example "", you will get an exception because the 
lengths do not match.

If you want a string object that is flexible in terms of length, you 
should use the type Ada.Strings.Unbounded.Unbounded_String, or make an 
instance of Ada.Strings.Bounded.Bounded_String with a suitable maximum 
length.

Or you could use a fixed-length string but always pad it with blanks (or 
whatever) up to the fixed length -- see Ada.Strings.Fixed for several 
useful operations on such strings. Depends on what you want...

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

* Re: Empty String confusion; Positive and Natural
  2021-11-29 22:50   ` Kevin Chadwick
  2021-11-30  8:29     ` Simon Wright
  2021-11-30  8:34     ` Niklas Holsti
@ 2021-11-30 10:00     ` Jeffrey R.Carter
  2021-11-30 12:17       ` Kevin Chadwick
  2 siblings, 1 reply; 13+ messages in thread
From: Jeffrey R.Carter @ 2021-11-30 10:00 UTC (permalink / raw)


On 2021-11-29 23:50, Kevin Chadwick wrote:
> 
> Hopefully I will have a doh moment when I get into the office in the morning and post code. I am getting a range check exception when I assign "" to a standard.String in a record by returning the record from a function. Surely, I must have caused it somehow.

It sounds as if you think type String is magic. String is a 
one-dimensional array type, no different than any other one-dimensional 
array type. It is declared in ARM A.1(37/3) 
(http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-1.html) as

type String is array(Positive range <>) of Character
       with Pack;

If you think that

type T is array (Positive range <>) of Integer;
V : T (1 .. 5);
...
V := (1 .. 0 => <>);

should work, then you don't understand arrays in Ada.

If you understand why that won't work, then

S : String (1 .. 5);
...
S := "";

is the exact same thing and fails in the same way for the same reason.

-- 
Jeff Carter
"I did not rob a bank. If I'd robbed a bank, everything
would be great. I tried to rob a bank, is what happened,
and they got me. I misspelled the note."
Take the Money and Run
140

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

* Re: Empty String confusion; Positive and Natural
  2021-11-30 10:00     ` Jeffrey R.Carter
@ 2021-11-30 12:17       ` Kevin Chadwick
  2021-11-30 12:54         ` J-P. Rosen
  0 siblings, 1 reply; 13+ messages in thread
From: Kevin Chadwick @ 2021-11-30 12:17 UTC (permalink / raw)


I have a create function that returns a type RunOutput

I always get range check failed even with a string of multiple characters.

type RunOutput(LogLen, OutputLen : Natural) is record
           LogStr : String(0..LogLen);
           Output : String(0..OutputLen);
...
end record;

I did have the following which works, so long as the string is not empty

type RunOutput(LogLen, OutputLen : Positive) is record
           LogStr : String(1..LogLen);
           Output : String(1..OutputLen);
...
end record;


P.s. I am not using exceptions with messages for log strings because I would rather use features that work with the zero footprint runtime as much as possible, where it makes sense.

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

* Re: Empty String confusion; Positive and Natural
  2021-11-30  8:21   ` Simon Wright
@ 2021-11-30 12:39     ` ldries46
  0 siblings, 0 replies; 13+ messages in thread
From: ldries46 @ 2021-11-30 12:39 UTC (permalink / raw)


Op 30-11-2021 om 9:21 schreef Simon Wright:
> ldries46 <bertus.dries@planet.nl> writes:
>
>> Empty_String : Unbounded_String := To_Unbounded_String("");
> * Given the name, you should probably declare it constant.
>
> * You don't need to initialize it, ARM 4.5(73) [1] says "If an object of
>    type Unbounded_String is not otherwise initialized, it will be
>    initialized to the same value as Null_Unbounded_String".
>
> * Ada.Strings.Unbounded.Null_Unbounded_String is a constant empty
>    string.
>
> [1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-4-5.html#p73
You are right. it should be

Empty_String : constant Unbounded_String := To_Unbounded_String("");

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

* Re: Empty String confusion; Positive and Natural
  2021-11-30 12:17       ` Kevin Chadwick
@ 2021-11-30 12:54         ` J-P. Rosen
  2021-11-30 13:12           ` Kevin Chadwick
  0 siblings, 1 reply; 13+ messages in thread
From: J-P. Rosen @ 2021-11-30 12:54 UTC (permalink / raw)


Le 30/11/2021 à 13:17, Kevin Chadwick a écrit :
> I have a create function that returns a type RunOutput
> 
> I always get range check failed even with a string of multiple characters.
> 
> type RunOutput(LogLen, OutputLen : Natural) is record
>             LogStr : String(0..LogLen);
>             Output : String(0..OutputLen);
> ...
> end record;
> 
> I did have the following which works, so long as the string is not empty
> 
> type RunOutput(LogLen, OutputLen : Positive) is record
>             LogStr : String(1..LogLen);
>             Output : String(1..OutputLen);
> ...
> end record;
> 
> 
> P.s. I am not using exceptions with messages for log strings because I would rather use features that work with the zero footprint runtime as much as possible, where it makes sense.
> 
Since String is indexed by Positive (not Natural), the lower bound 
cannot be 0. OTOH, there is no check for bounds of empty arrays, 
therefore the following would work:

type RunOutput(LogLen, OutputLen : Natural) is record
              LogStr : String(1..LogLen);
              Output : String(1..OutputLen);

and you can have empty strings if Loglen or Outputlen is 0, without 
Constraint_Error. (It's precisely for that reason that there is no check 
of bounds of empty arrays).
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

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

* Re: Empty String confusion; Positive and Natural
  2021-11-30 12:54         ` J-P. Rosen
@ 2021-11-30 13:12           ` Kevin Chadwick
  0 siblings, 0 replies; 13+ messages in thread
From: Kevin Chadwick @ 2021-11-30 13:12 UTC (permalink / raw)



> Since String is indexed by Positive (not Natural), the lower bound 
> cannot be 0. OTOH, there is no check for bounds of empty arrays, 
> therefore the following would work:
> type RunOutput(LogLen, OutputLen : Natural) is record
> LogStr : String(1..LogLen); 
> Output : String(1..OutputLen); 
> 
> and you can have empty strings if Loglen or Outputlen is 0, without 
> Constraint_Error. (It's precisely for that reason that there is no check 
> of bounds of empty arrays). 

I See, 
Thanks everyone

I apologise for posting the original thread whilst leaving the office and 
posting without the code upfront.

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

end of thread, other threads:[~2021-11-30 13:12 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29 17:34 Empty String confusion; Positive and Natural Kevin Chadwick
2021-11-29 18:05 ` Jeffrey R.Carter
2021-11-29 19:19 ` Niklas Holsti
2021-11-29 22:50   ` Kevin Chadwick
2021-11-30  8:29     ` Simon Wright
2021-11-30  8:34     ` Niklas Holsti
2021-11-30 10:00     ` Jeffrey R.Carter
2021-11-30 12:17       ` Kevin Chadwick
2021-11-30 12:54         ` J-P. Rosen
2021-11-30 13:12           ` Kevin Chadwick
2021-11-30  7:40 ` ldries46
2021-11-30  8:21   ` Simon Wright
2021-11-30 12:39     ` ldries46

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