Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Constraint error?

4 views
Skip to first unread message

McDoobie

unread,
Jun 3, 2001, 6:30:05 PM6/3/01
to
Alright, so I wrote a simple as hell Ada program that figures out the
volume of an object.

And it worked! I danced around, got all happy, and all the peasants
rejoiced. Or so I thought.

The program works with some values, but then raises a constraint error
with others.

Because it's so small, I'll post it up here.

with Ada.Text_IO, Ada.Float_Text_IO; use Ada.Text_IO, Ada.Float_Text_IO;

procedure simplevolume is

Height : Float; Width : Float; Length : Float;
-- The Variables for finding the volume of a shape.

TotalVolume : Float;
-- The variable that will hold the results.

s : string(1..5); -- This variable contains 5 chars. Duh!
len : natural;

begin

Put_Line( "Enter the Length here: ");
Get_Line( s, len );
Length := float'value( s );
New_Line;
Put_Line( "Enter the Width here: ");
Get_Line( s, len );
Width := float'value( s );
New_Line;
Put_Line( "Enter the Height here: ");
Get_Line( s, len );
Height := float'value( s );
New_Line;
-- It should be obvious what's occurring here. Were collecting the
-- variables of the shape.

TotalVolume := ((Length * Width) * Height);

Put_Line( "The total Volume of the shape is: " & TotalVolume'img );
New_Line; Put_Line( "Goodbye!" );

end simplevolume;

No fancy loops or anything of that nature. Just a straight drop though the
code program.

Now if I enter like 12.3 for the Length, it works fine, but if I enter
like 5.0, I get a constraint error.

The specific error I get is...

raised CONSTRAIN_ERROR : s-valuti.adb:236

Now, could someone explain what I'm doing wrong here? I'm a little fuzzy
on constraint errors.

Thanks.

McDoobie ch...@dont.spam.me

P.S. Try not to laugh. I'm still a greenhorn okay. ;->

David C. Hoos, Sr.

unread,
Jun 3, 2001, 7:13:40 PM6/3/01
to
One obvious error is using the entire string "s" as the argument of the
Float'Value attribute function call.

You should be using Float'Value (S (1 .. len)

Also, there's probably no reason to have the length of "s"
so small -- why not make it ten or fifteen characters long, so as to give
greater flexibility as to what the user can enter.

"McDoobie" <som...@nospam.net> wrote in message
news:NTyS6.25500$DG1.4...@news1.rdc1.mi.home.com...

McDoobie

unread,
Jun 3, 2001, 7:26:03 PM6/3/01
to
In article <ywzS6.5844$Zy.43...@newsrump.sjc.telocity.net>, "David C.
Hoos, Sr." <david.c...@ada95.com> wrote:

> One obvious error is using the entire string "s" as the argument of the
> Float'Value attribute function call.
>
> You should be using Float'Value (S (1 .. len)
>
> Also, there's probably no reason to have the length of "s" so small --
> why not make it ten or fifteen characters long, so as to give greater
> flexibility as to what the user can enter.

That did it.

I'm gonna to pay much closer attention to the arguments I pass around.

Thanks for the help.

I'm really starting to like Ada, but compared to using C it still feels like
I'm wrestling a gorilla. I'll get it yet.

Thanks again.

McDoobie
ch...@dont.spam.me

Ted Dennison

unread,
Jun 4, 2001, 11:42:58 AM6/4/01
to
In article <fIzS6.25747$DG1.4...@news1.rdc1.mi.home.com>, McDoobie says...

>I'm really starting to like Ada, but compared to using C it still feels like
>I'm wrestling a gorilla. I'll get it yet.

What mostly seems to be tripping you up here is string handling. You shouldn't
feel bad about that, because that's the thing that frustrates most beginners.
Ada's string handling is actually much *more* powerful and convienent than C's
in most cases, but you have to go about things quite differently.

The main thing to realize is that an Ada string is *not* just an array of
characters; its also a range within that array (a starting and ending index). If
you don't specify that range explicitly, then most routines assume its the first
character of the array to the last. The character ASCII.NUL has *no* special
significance in Ada.

Now this philosophy forces 3 main methods for dealing with strings on you. The
first is that you declare your string arrays large enough to hold whatever you
might ever want to put in them, and keep track of the valid characters in
separate variables. Usually the start of the string can be assumed to be at the
first character ('first), so you only really have to keep track of the logical
end. This is the method that has to be used with the Text_IO.Get_* routines, as
they use this technique for their interface. Likewise, if you write your own
procedures that use a string as an "out" or "in out" parameter, you will also
need to pass out a "length" parameter.

The second way to deal with strings is to delay their declaration until you can
assign the value directly into them. That way you can leave the bounds off of
the declaration and let it size itself perfectly to the contents. This is the
easiest method to deal with, if you can use it. Most of the attributes
('whatever) that deal with strings can be used with this method. If you want to
use this method in your own subprograms, you should endevor to always return
strings as function return values. Of course this method only works if you don't
plan on changing the contents. For example (my apologies if my newsreader hoses
the formatting):

declare
Width_Answer : constant String := Answer (1..Answer_Length);
begin
-- work with Width_Answer in here.
..
end;

Now if you *do* need to change the string's contents, or have to declare it
before you can assign into it, then you can use the third way: the
Ada.Strings.Unbounded (or Ada.Strings.Bounded) package. Few predefined Ada
routines use these packages, but you may have a good use for them in your own
code.

Make sure you are acquainted with all the language defined attributes that deal
with strings and arrays. They are central to how you do strings in Ada.

As a final point, remember that strings are really just arrays, so the first two
techniques work just as well for arrays as they do for strings. :-)

---
T.E.D. homepage - http://www.telepath.com/dennison/Ted/TED.html
home email - mailto:denn...@telepath.com

Marin David Condic

unread,
Jun 4, 2001, 12:12:24 PM6/4/01
to
I almost always find it easier to immediately jump to Ada.Strings.Unbounded
because to used fixed strings, you just end up duplicating in some manner
the things you get automagically in Unbounded. The only problem is that in
Standard Issue Ada, you still need to know about fixed strings when first
learning the language because they are the basis for string literals &
Text_IO. You can shield the beginner from the Text_IO part with a
non-standard skin* over it. However, to use string literals, you've got to
still understand the fixed array of characters aspect of it. The same
applies to the attributes that have something to do with strings ('Image and
'Value come to mind.)

I think it would be useful for beginning users of Ada to be shown everything
in the context of Unbounded strings for their simplicity and ease of use.
I'm just not sure it is possible to totally avoid talking about standard
strings and Ada.Strings.Fixed. Is it better for the beginner to be forced to
learn about fixed strings and after all the pain be shown how to use
.Bounded and .Unbounded? Or should an approach be found to talk about
everything from the perspective of Unbounded & then ease the newbie into the
more difficult aspects later? And of course, as you observe, everything you
learn about fixed strings applies to any array one might use, so maybe its
best to get it over with up front. It certainly isn't any worse than
teaching about strings in C - but that isn't saying much. One would like to
claim that Ada is easier than C - which it is - but WRT strings, there is
just a lot to know and a paradigm shift to go through before the "easier"
part shows up.


*Maybe "skin" is the word to distinguish between a thin binding, a thick
binding and a subsystem? You have a "binding" a "skin" and a "subsystem"
wherein a "skin" shields you from uncomfortable parameters, but doesn't add
any significant functionality? But this is another debate...

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas www.pacemicro.com
Enabling the digital revolution
e-Mail: marin....@pacemicro.com
Web: http://www.mcondic.com/


"Ted Dennison" <denn...@telepath.com> wrote in message
news:60OS6.3835$v4.1...@www.newsranger.com...

Robert A Duff

unread,
Jun 4, 2001, 4:50:19 PM6/4/01
to
Ted Dennison<denn...@telepath.com> writes:

> Ada's string handling is actually much *more* powerful and convienent

> than C's in most cases, ...

That's sort of like saying that if you want a nice steak dinner, a
"Whopper with Cheese" is better than a "Big Mac". ;-)

I don't disagree with any of your advice. But I couldn't resist pointer
out that string handling is a pain in Ada as well.

- Bob

Robert A Duff

unread,
Jun 4, 2001, 4:52:53 PM6/4/01
to
"Marin David Condic" <marin.condic...@pacemicro.com> writes:

> I think it would be useful for beginning users of Ada to be shown everything
> in the context of Unbounded strings for their simplicity and ease of use.

I agree. But as you say, you unfortunately have to keep converting back
and forth to String, and you have to know about operations of type
String as well. Too bad Unbounded strings don't have a superset of the
capabilities of String (eg, literals, indexing, I/O).

> *Maybe "skin" is the word to distinguish between a thin binding, a thick
> binding and a subsystem? You have a "binding" a "skin" and a "subsystem"
> wherein a "skin" shields you from uncomfortable parameters, but doesn't add
> any significant functionality? But this is another debate...

"Skin" is what I would call a "wrapper".

- Bob

Ted Dennison

unread,
Jun 4, 2001, 5:13:32 PM6/4/01
to
In article <wccvgmc...@world.std.com>, Robert A Duff says...

>I don't disagree with any of your advice. But I couldn't resist pointer
>out that string handling is a pain in Ada as well.

Well..perhaps you are more used to specialized string-handling languages than I
am. I don't find it a pain at all, as long as you can keep things in
perfectly-sized fixed strings. Generally, that is no problem, but I mostly do
system programming. I'll admit there are probably some domains where its a lot
tougher than I'm used to.

So I guess I'm saying I disagree with you, but I might not have the whole
picture either.

Ehud Lamm

unread,
Jun 4, 2001, 5:44:51 PM6/4/01
to

Ted Dennison <denn...@telepath.com> wrote in message
news:0SSS6.4214$v4.2...@www.newsranger.com...

> In article <wccvgmc...@world.std.com>, Robert A Duff says...
> >I don't disagree with any of your advice. But I couldn't resist pointer
> >out that string handling is a pain in Ada as well.
>
> Well..perhaps you are more used to specialized string-handling languages
than I
> am. I don't find it a pain at all, as long as you can keep things in
> perfectly-sized fixed strings. Generally, that is no problem, but I mostly
do
> system programming. I'll admit there are probably some domains where its a
lot
> tougher than I'm used to.
>
> So I guess I'm saying I disagree with you, but I might not have the whole
> picture either.
>

I feel that we use the term string to refer to many different abstractions.
In fact the only thing common to all of them is that they represent
sequences of characters (even the character set question opens a can of
worms).

I rememeber that working with Rexx on an IBM mainframe I kept thinking
"hell, Snobol or Perl are much more powerful when it comes to strings." -
since the Rexx parse command is basically better suited to handle strings
with fixed layout. But this is the kind of records you usually find in the
kind of world Rexx was (originally) created for.

Now consider the confusion of someone coming from a Pascal or C background,
and seeing Ada strings for the first time.
They are called strings so he is sure that they are basically the same
abstraction as he is used to. So the C hacker will try to insert \0 all over
the place, and think that legnth should be found using something like
strlen. 'length is going to look crzay as hell, always returning the same
length...
The Pascal programmer implicitly assumes that strings remember their current
length, shrinking and expanding as needed.
The Ada string type, being an unconstrained array type, is of course
different than both of these.
Is it more natural to use? I don't think so. This is not meant as a
criticism. The other approaches described above are unnatural too - only
some times people learn them first.

I think that most poeple looking from a fresh point of view on the problem
would want some form of unbounded strings. Most language designers find such
strings too abstract, and prefer to start from more basic array of
characters types. This usually means that the library supplied string types
(like Unbounded in Ada) are less elegant to use, and don't have as nice a
syntax.

This is one reason why string handling languages are usually niche
languages, with specially designed syntax, suporting a richer string
abstraction.


P.S
But do check the GNAT Spitbol packages.


--
Ehud Lamm msl...@mscc.huji.ac.il
http://purl.oclc.org/NET/ehudlamm <== Me!

Marc A. Criley

unread,
Jun 5, 2001, 8:21:52 AM6/5/01
to
Ted Dennison wrote:
>
>
> The second way to deal with strings is to delay their declaration until you can
> assign the value directly into them. That way you can leave the bounds off of
> the declaration and let it size itself perfectly to the contents. This is the
> easiest method to deal with, if you can use it. Most of the attributes
> ('whatever) that deal with strings can be used with this method. If you want to
> use this method in your own subprograms, you should endevor to always return
> strings as function return values. Of course this method only works if you don't
> plan on changing the contents. For example (my apologies if my newsreader hoses
> the formatting):
>
> declare
> Width_Answer : constant String := Answer (1..Answer_Length);
> begin
> -- work with Width_Answer in here.
> ..
> end;

Ada 95 removed the requirement that a String declaration as used in the
above example be declared _constant_. The string will be properly
sized, but you can now modify it to your heart's content, just can't
change the size.

Marc A. Criley
Senior Staff Engineer
Quadrus Corporation
www.quadruscorp.com

Ted Dennison

unread,
Jun 5, 2001, 11:22:11 AM6/5/01
to
In article <3B1CC1FE...@earthlink.net>, Marc A. Criley says...

>
>Ted Dennison wrote:
>> strings as function return values. Of course this method only works if you >> don't plan on changing the contents. For example (my apologies if my

>Ada 95 removed the requirement that a String declaration as used in the


>above example be declared _constant_. The string will be properly
>sized, but you can now modify it to your heart's content, just can't
>change the size.

True. But its quite rare that you might need to change the contents but never
the size. Thus this relaxation is mostly useful for those slightly less rare
instances where you need it to not be constant for technical reasons. (eg: You
need to create an access to it using a non-constant access type. You need to use
it in an "access" parameter. You need to pass it into a routine that doesn't
modify it, but uses "in out" for the parameter anyway.)

I'll admit its a possibility, but not a common enough one to worry a beginner
with.

0 new messages