comp.lang.ada
 help / color / mirror / Atom feed
* not X'Length
@ 2008-05-15  9:19 Georg Bauhaus
  2008-05-15  9:39 ` christoph.grein
  0 siblings, 1 reply; 8+ messages in thread
From: Georg Bauhaus @ 2008-05-15  9:19 UTC (permalink / raw)


What do you think of the error messages referring to line 9?
Does it make sense for a a programmer to expect that a compiler
can/should become especially upset when it sees (or maybe,
does not see) "not <universal_integer>"?

Parentheses and "not in" were left out deliberately.

procedure B is
   X: array(1 .. 10) of Boolean;
   type Gotcha is mod 2**8;
begin
   if X'Length in Positive then
      null;
   end if;

   if not X'Length in Positive then
      null;
   end if;

   if not X'Length in Gotcha then
      null;
   end if;

   if not Natural'(X'Length) in Positive then
      null;
   end if;
end B;

Copyright 1992-2005 Free Software Foundation, Inc.

Compiling: b.adb (source file time stamp: 2008-05-15 08:51:18)

     1. procedure B is
     2.    X: array(1 .. 10) of Boolean;
     3.    type Gotcha is mod 2**8;
     4. begin
     5.    if X'Length in Positive then
                       |
        >>> warning: condition is always True

     6.       null;
     7.    end if;
     8.
     9.    if not X'Length in Positive then
                           |
        >>> incompatible types

    10.       null;
    11.    end if;
    12.
    13.    if not X'Length in Gotcha then
              1            2
        >>> warning: not expression should be parenthesized here
        >>> warning: condition is always True

    14.       null;
    15.    end if;
    16.
    17.    if not Natural'(X'Length) in Positive then
              |
        >>> operator "Not" not defined for type "Standard.Natural"

    18.       null;
    19.    end if;
    20. end B;

 20 lines: 2 errors, 3 warnings
gnatmake: "b.adb" compilation error


---8<---8<---8<---

    Copyright (c) 1994-2006, SofCheck, Inc.  All Rights Reserved.
Compiling 'b.adb': Thu May 15 10:59:19 2008

Source file: b.adb   Thu May 15 11:08:34 2008

    1 procedure B is
    2    X: array(1 .. 10) of Boolean;
    3    type Gotcha is mod 2**8;
    4 begin
    5    if X'Length in Positive then
    6       null;
    7    end if;
    8
    9    if not X'Length in Positive then
                         *
*****Error: LRM:8.6(28) Inappropriate operands for "IN" operation,
continuing
   10       null;
   11    end if;
   12
   13    if not X'Length in Gotcha then
   14       null;
   15    end if;
   16
   17    if not Natural'(X'Length) in Positive then
            *
*****Error: LRM:8.4(1) Unary operator "NOT" on Integer not directly visible,
*****        use clause or conversion might be needed
   18       null;
   19    end if;
   20 end B;



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

* Re: not X'Length
  2008-05-15  9:19 not X'Length Georg Bauhaus
@ 2008-05-15  9:39 ` christoph.grein
  2008-05-15 10:12   ` christoph.grein
  2008-05-15 20:48   ` Georg Bauhaus
  0 siblings, 2 replies; 8+ messages in thread
From: christoph.grein @ 2008-05-15  9:39 UTC (permalink / raw)


From RM 4.4 follows that this is equivalent to

if (not X'Length) in Positive then

Now Universal_Integer (X'Length is of this type) has no operators, so
it has to be converted to an appropriate type. This is Integer (or, to
be very precise, the type of Integer) in this case. But then there is
no "not" defined for this type. So the compiler is correct.



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

* Re: not X'Length
  2008-05-15  9:39 ` christoph.grein
@ 2008-05-15 10:12   ` christoph.grein
  2008-05-15 20:48   ` Georg Bauhaus
  1 sibling, 0 replies; 8+ messages in thread
From: christoph.grein @ 2008-05-15 10:12 UTC (permalink / raw)


Nachtrag: Warum einfach, wenn's auch kompliziert geht.

if X'Length not in Positive then  -- was meant (I gather), implicit
type conversion to Integer; can be simplified to

if X'Length = 0 then  -- implicit type conversion (to root_integer -
not sure about this, too lazy to look it up) here



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

* Re: not X'Length
  2008-05-15  9:39 ` christoph.grein
  2008-05-15 10:12   ` christoph.grein
@ 2008-05-15 20:48   ` Georg Bauhaus
  2008-05-15 22:20     ` Adam Beneschan
  2008-05-16 12:52     ` Stephen Leake
  1 sibling, 2 replies; 8+ messages in thread
From: Georg Bauhaus @ 2008-05-15 20:48 UTC (permalink / raw)


christoph.grein@eurocopter.com wrote:
> From RM 4.4 follows that this is equivalent to
> 
> if (not X'Length) in Positive then
> 
> Now Universal_Integer (X'Length is of this type) has no operators, so
> it has to be converted to an appropriate type. This is Integer (or, to
> be very precise, the type of Integer) in this case. But then there is
> no "not" defined for this type. So the compiler is correct.

While the compilers are correct, on the programmer's part the
issue is not that easy to understand in general.
You have demonstrated why this is so. Hence my original
question about programmer expectations regarding improved
compiler's diagnostics in this case.

Apparently GNAT can do better in a similar case,

 if not X'Length in Gotcha then  -- Gotcha a mod type

"warning: not expression should be parenthesized here"

for whatever reason.

The issue is that the compilers are correct but they do
not point at the original programmer mistake. While this isn't
unusual, Ada compilers seem to be very good at pointing to
the real cause.


Suppose you are a willing but naive Ada programmer you had
written (and thought)

IF <L> IN <R> THEN       -- <==*=  IF <E> THEN

o.K., no error. You write

IF not <L> IN <R> THEN   -- <==*= IF not <E> THEN  -- Doh!

and are being told "incompatible types", which is a technically
correct whipping. But the thing that has changed, you thought,
is the addition of negating the original Boolean expression.
You thought. And now there is a type issue?

IF not X'Length IN Positive THEN

(a) it's a precedence thing and
(b) as you demonstrate, it takes several mental indirections
to interpret X'Length correctly
    (b.1) as a value of some unnamed type that
    (b.2) will potentially be of a type that,
          (b.2.*) seen without regard to "IN <R>"
          (b.2.+) seen after "NOT"
is nothing you would have expected. You think,
"How on earth can I apply a Boolean operator to an array length?"

I'm *not* saying the compilers are incorrect.
But maybe they could be a bit more helpful in this case (as in the
second GNAT warning).
This is why I had considered filing an enhancement request, unless
this request is obviously too ambitious. I simply don't know.



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

* Re: not X'Length
  2008-05-15 20:48   ` Georg Bauhaus
@ 2008-05-15 22:20     ` Adam Beneschan
  2008-05-16  8:04       ` Manuel Collado
  2008-05-16  8:15       ` Georg Bauhaus
  2008-05-16 12:52     ` Stephen Leake
  1 sibling, 2 replies; 8+ messages in thread
From: Adam Beneschan @ 2008-05-15 22:20 UTC (permalink / raw)


On May 15, 1:48 pm, Georg Bauhaus <see.reply...@maps.futureapps.de>
wrote:
> christoph.gr...@eurocopter.com wrote:
> > From RM 4.4 follows that this is equivalent to
>
> > if (not X'Length) in Positive then
>
> > Now Universal_Integer (X'Length is of this type) has no operators, so
> > it has to be converted to an appropriate type. This is Integer (or, to
> > be very precise, the type of Integer) in this case. But then there is
> > no "not" defined for this type. So the compiler is correct.
>
> While the compilers are correct, on the programmer's part the
> issue is not that easy to understand in general.
> You have demonstrated why this is so. Hence my original
> question about programmer expectations regarding improved
> compiler's diagnostics in this case.

You may be right that a better diagnostic would help in this specific
case.  But a programmer cannot expect a compiler to be a mind-reader.
And a compiler writer can't really go through every possible weird
combination of things to figure out what sorts of accidental trouble a
programmer could get themselves into---there are just too many
possibilities.  About all a compiler writer can do is respond to
particular situations when they get noticed.  So go ahead and file
your enhancement request, but please don't criticize the compiler (or
the vendor) next time you screw up in a different way and the compiler
can't figure out what you're trying to do.  That would be asking far
too much.

Your original post said something about expecting the compiler to
complain about "not" being applied to a universal integer.  I'm not
quite sure what your intent was, but applying "not" to a universal
integer is quite legitimate where modular types are concerned.
Something like

   (Z and not 1)

is a good way to clear a bit in Z, if Z's type is a modular type.
Maybe applying "not" to an attribute that returns a universal integer
(like "not X'Length") is less legitimate---but even then, if X'Length
is known to be a power of 2, something like (not (X'Length-1)) can be
used to yield a mask that can be used for alignment/rounding when
AND'ed with another modular value.

                                  -- Adam



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

* Re: not X'Length
  2008-05-15 22:20     ` Adam Beneschan
@ 2008-05-16  8:04       ` Manuel Collado
  2008-05-16  8:15       ` Georg Bauhaus
  1 sibling, 0 replies; 8+ messages in thread
From: Manuel Collado @ 2008-05-16  8:04 UTC (permalink / raw)


Adam Beneschan escribi�:
> On May 15, 1:48 pm, Georg Bauhaus <see.reply...@maps.futureapps.de>
> wrote:
>> christoph.gr...@eurocopter.com wrote:
>>> From RM 4.4 follows that this is equivalent to

>>> if (not X'Length) in Positive then

>>> Now Universal_Integer (X'Length is of this type) has no operators, so
>>> it has to be converted to an appropriate type. This is Integer (or, to
>>> be very precise, the type of Integer) in this case. But then there is
>>> no "not" defined for this type. So the compiler is correct.

>> While the compilers are correct, on the programmer's part the
>> issue is not that easy to understand in general.
>> You have demonstrated why this is so. Hence my original
>> question about programmer expectations regarding improved
>> compiler's diagnostics in this case.
> 
> You may be right that a better diagnostic would help in this specific
> case.  But a programmer cannot expect a compiler to be a mind-reader.
> And a compiler writer can't really go through every possible weird
> combination of things to figure out what sorts of accidental trouble a
> programmer could get themselves into---there are just too many
> possibilities.  About all a compiler writer can do is respond to
> particular situations when they get noticed.

Perhaps the compiler could state how the expression is parsed, so the 
diagnostic message can be better understood:

    if not X'Length in Positive then
                    |
    >>> incompatible types: parsed as
    >>> if (not X'Length) in Positive then

Just my 2c.
-- 
Manuel Collado - http://lml.ls.fi.upm.es/~mcollado



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

* Re: not X'Length
  2008-05-15 22:20     ` Adam Beneschan
  2008-05-16  8:04       ` Manuel Collado
@ 2008-05-16  8:15       ` Georg Bauhaus
  1 sibling, 0 replies; 8+ messages in thread
From: Georg Bauhaus @ 2008-05-16  8:15 UTC (permalink / raw)


Points taken.

Adam Beneschan wrote:
> Your original post said something about expecting the compiler to
> complain about "not" being applied to a universal integer.  I'm not
> quite sure what your intent was, but applying "not" to a universal
> integer is quite legitimate where modular types are concerned.

I was just wondering whether a compiler could know that provided
<R> is statically an integer type and <L> of a "perfectly normal
magic type", then let <R> have more weight in biasing the diagnostic
of <L> IN <R> so have the compiler consider the genesis of the latter.
But I will stop speculating about things behind the compiler's walls
and let the makers do other work undisturbed.

> Something like
>
>    (Z and not 1)
> 
> is a good way to clear a bit in Z, if Z's type is a modular type.

I guess as a matter of personal preference I'd choose (Z and not 2#1#)
and (not Unsigned_8'(X'Length-1)) or similar. OK, enough said.



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

* Re: not X'Length
  2008-05-15 20:48   ` Georg Bauhaus
  2008-05-15 22:20     ` Adam Beneschan
@ 2008-05-16 12:52     ` Stephen Leake
  1 sibling, 0 replies; 8+ messages in thread
From: Stephen Leake @ 2008-05-16 12:52 UTC (permalink / raw)


Georg Bauhaus <see.reply.to@maps.futureapps.de> writes:

> I'm *not* saying the compilers are incorrect.
> But maybe they could be a bit more helpful in this case (as in the
> second GNAT warning).
> This is why I had considered filing an enhancement request, unless
> this request is obviously too ambitious. I simply don't know.

Only the compiler vendors can say what is "too ambitious" for them. I
am often pleasantly surprised at what AdaCore can do to improve error
messages.

So submit this request, and include your subsequent short tutorial on
how an eager Ada newbie would fall victim.

The vendors can always say "no".

-- 
-- Stephe



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

end of thread, other threads:[~2008-05-16 12:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-15  9:19 not X'Length Georg Bauhaus
2008-05-15  9:39 ` christoph.grein
2008-05-15 10:12   ` christoph.grein
2008-05-15 20:48   ` Georg Bauhaus
2008-05-15 22:20     ` Adam Beneschan
2008-05-16  8:04       ` Manuel Collado
2008-05-16  8:15       ` Georg Bauhaus
2008-05-16 12:52     ` Stephen Leake

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