From: Alex Mentis on
I'm disappointed with some allowed syntax that seems a little error-
prone. Consider the following code:

with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;

procedure Main is

Nat : constant Natural := 0;
Pos : Positive;

begin

Get (Pos);
Put (Positive'Min(Nat, Pos)); -- Ada does not require the Min
attribute to enforce a Positive result

end Main;

This program happily outputs that the minimum of (0 and whatever
positive value you enter) is 0. Now, I concede that the program is
working exactly as the ARM specifies. The Min (and Max) attribute
functions accept and return types of S'Base, in this case
Positive'Base. But doesn't it seem like a bit of a tease to allow a
programmer to specify S'Min if the compiler is allowed to ignore the
type of S in the function's parameter list and the program does not
raise a Constraint_Error at run-time if it returns a value outside the
range of type S?

If it's too hard to enforce strictly then maybe the functions should
be named Unchecked_Min/Unchecked_Max. Or maybe the programmer should
be constrained to using the attributes with only a base type. Or, at
the very least, can't the compiler generate a warning about this? I
turned on all warnings in GPS and got nothing.

Things that make you go hmmm...

Alex
From: Martin on
On Apr 27, 8:34 pm, Alex Mentis <asmen...(a)gmail.com> wrote:
> I'm disappointed with some allowed syntax that seems a little error-
> prone.  Consider the following code:
>
> with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
>
> procedure Main is
>
>    Nat : constant Natural := 0;
>    Pos : Positive;
>
> begin
>
>    Get (Pos);
>    Put (Positive'Min(Nat, Pos)); -- Ada does not require the Min
> attribute to enforce a Positive result
>
> end Main;
>
> This program happily outputs that the minimum of (0 and whatever
> positive value you enter) is 0.  Now, I concede that the program is
> working exactly as the ARM specifies.  The Min (and Max) attribute
> functions accept and return types of S'Base, in this case
> Positive'Base.  But doesn't it seem like a bit of a tease to allow a
> programmer to specify S'Min if the compiler is allowed to ignore the
> type of S in the function's parameter list and the program does not
> raise a Constraint_Error at run-time if it returns a value outside the
> range of type S?
>
> If it's too hard to enforce strictly then maybe the functions should
> be named Unchecked_Min/Unchecked_Max.  Or maybe the programmer should
> be constrained to using the attributes with only a base type.  Or, at
> the very least, can't the compiler generate a warning about this?  I
> turned on all warnings in GPS and got nothing.
>
> Things that make you go hmmm...
>
> Alex

If you want the check, this should do:

begin
Get (Pos);
Put (Positive (Positive'Min(Nat, Pos)));
end ...

-- Martin
From: Robert A Duff on
Martin <martin.dowie(a)btopenworld.com> writes:

> Put (Positive (Positive'Min(Nat, Pos)));

That works, but I think a qualified expression is better:

Put (Positive'(Positive'Min(Nat, Pos)));

By the way, there are lots of attributes that work
like this (use the base subtype). It's not just Min
and Max.

- Bob
From: Randy Brukardt on
"Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote in message
news:wcczl0o7g13.fsf(a)shell01.TheWorld.com...
> Martin <martin.dowie(a)btopenworld.com> writes:
>
>> Put (Positive (Positive'Min(Nat, Pos)));
>
> That works, but I think a qualified expression is better:
>
> Put (Positive'(Positive'Min(Nat, Pos)));
>
> By the way, there are lots of attributes that work
> like this (use the base subtype). It's not just Min
> and Max.

Right. Attributes mostly type-related, not subtype-related. The name in the
prefix serves to identify the type, not the subtype (there are no named
types in Ada, only named subtypes).

All of 'Succ, 'Pred, 'Val, and 'Value work this way, and there are probably
many, many more. Even 'First and 'Last technically work this way (although
it doesn't matter in that case).

Randy.


From: Alex Mentis on
On Apr 27, 5:16 pm, Robert A Duff <bobd...(a)shell01.TheWorld.com>
wrote:
> Martin <martin.do...(a)btopenworld.com> writes:
> >    Put (Positive (Positive'Min(Nat, Pos)));
>
> That works, but I think a qualified expression is better:
>
>    Put (Positive'(Positive'Min(Nat, Pos)));
>
> By the way, there are lots of attributes that work
> like this (use the base subtype).  It's not just Min
> and Max.
>
> - Bob

I think you all missed my point: allowing the programmer to specify a
constraint in situations where the constraint will not be enforced
could cause confusion/error for someone who doesn't have the entire
ARM memorized....

Yes, I know there are ways to force Ada to do the check, like explicit
type conversion and qualified expressions. That's pretty ugly,
though. If I already have to put the type in front of the attribute,
why should I have to put the type in front of that again? As long as
we're posting work-arounds, though, I suppose I would use the
following:

with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;

procedure Main is

function Min(Value_1, Value_2 : Integer) return Integer renames
Integer'Min;

Nat : constant Natural := 0;
Pos : Positive;

begin

Get (Pos);
Put (Positive'(Min(Nat, Pos))); -- return a Positive result from
renamed Min else raise a Constraint_Error

end Main;