comp.lang.ada
 help / color / mirror / Atom feed
From: Robert Dewar <robert_dewar@my-deja.com>
Subject: Re: LLQ: -1 a valid boolean?
Date: 2000/05/21
Date: 2000-05-21T00:00:00+00:00	[thread overview]
Message-ID: <8g8o3b$9l0$1@nnrp1.deja.com> (raw)
In-Reply-To: 39253CD0.C8DC893D@telepath.com

In article <39253CD0.C8DC893D@telepath.com>,
  Ted Dennison <dennison@telepath.com> wrote:
> You'd think that a value that is legal in situ ought to be
> legal to assign as well. Then again, if Ada_Boolean'Size = 8
> or 32 or something, then I can see where one might argue that
> a value of -1 (all bits set) is out of range of the possible
> Boolean values, and thus should raise
> Constraint_Error.
>
> So what's right?

Not only is the compiler's behavior conforming, it is actually
what one would expect, given that you most certainly expect
that boolean objects have a size of 8 (the choice of a size
of 1 for boolean objects is typically impractical on most
architectures due to the task indepedence requirement).

Your code is just wrong here, and you are going to have to
deal with these booleans in a completely different manner.

If your compiler implements Interfaces.Fortran, then everything
should be fine, since the type Logical should work properly.

However, you may well find that even if your compiler says it
supports Interfaces.Fortran, it may get Logical wrong. That
was certainly the case with earlier versions of GNAT (a bad
gap in the ACVC tests is that there are no tests for proper
implementation of Logical, and the requirements are subtle).

The trouble is that Logical is derived from Boolean, but is
required to have completely different semantics from normal
Booleans, namely zero/nonzero semantics like C.

What we did in GNAT was implement a completely general facility
that allows derived booleans to be given a convention of C or
Fortran, and then they implement full zero/nonzero semantics.
This was definitely a non-trivial implementation effort, since
all sorts of special cases arise (we now for the first time have
a many-to-one mapping for the pos function for example).

So in GNAT, you can solve this problem by simply using pragma
Convention (Fortran, ...) but I don't think any other compilers
implement this feature in general terms. Whether any other
compilers properly implement Logical I don't know. Here's the
test we use for this purpose in our regression suite at Ada
Core Technologies:

with Interfaces.Fortran; use Interfaces.Fortran;
with Unchecked_Conversion;
with Text_IO; use Text_IO;

procedure q is
   B : Boolean;
   L : Logical;
   I : Short_Short_Integer;

   Passed : Boolean := True;

   function To_L is new Unchecked_Conversion (Integer, Logical);
   function From_B is new Unchecked_Conversion (Boolean,
Short_Short_Integer);

   AL : array (1 .. 1) of Logical;

begin
   goto Next;
   <<Next>>
   L := To_L (2);
   AL (1) := L;

   if Logical'Pos (L) /= 1 then
      Put_Line ("wrong pos value for L");
      Passed := False;
   end if;

   if L then
      null;
   else
      Put_Line ("true value of L does not look true");
      Passed := False;
   end if;

   if not L'Valid then
      Put_Line ("L looks invalid");
      Passed := False;
   end if;

   if  (L > True or True < L) then
      Put_Line ("complex condition handled incorrectly");
   end if;

   if  (L > True or else True < L) then
      Put_Line ("complex short circuit condition handled
incorrectly");
   end if;

   if Logical'Pos (AL (1)) /= 1 then
      Put_Line ("wrong pos value for AL (1)");
      Passed := False;
   end if;

   if AL (1) then
      null;
   else
      Put_Line ("true value of AL (1) does not look true");
      Passed := False;
   end if;

   if not AL (1)'Valid then
      Put_Line ("AL (1) looks invalid");
      Passed := False;
   end if;

   if  (AL (1) > True or True < AL (1)) then
      Put_Line ("complex condition handled incorrectly");
   end if;

   if  (AL (1) > True or else True < AL (1)) then
      Put_Line ("complex short circuit condition handled
incorrectly");
   end if;

   B := Boolean (L);
   I := From_B (B);

   if I /= 1 then
      Put_Line ("wrong boolean value from conversion");
      Passed := False;
   end if;

   if Passed then
      Put_Line ("passed");
   end if;
end q;

(well there are some other tests as well, but they are based
on customer proprietary code, so they cannot be posted. It was
a customer doing interfacing to Fortran who first brought this
to our attention).

Robert Dewar
Ada Core Technologies

P.S. This was implemented in GNAT version 3.12


Sent via Deja.com http://www.deja.com/
Before you buy.




  parent reply	other threads:[~2000-05-21  0:00 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-05-19  0:00 LLQ: -1 a valid boolean? Ted Dennison
2000-05-19  0:00 ` Jeff Carter
2000-05-20  0:00   ` Ted Dennison
2000-05-21  0:00 ` Robert Dewar [this message]
2000-05-23  0:00   ` Ted Dennison
2000-05-23  0:00     ` David C. Hoos, Sr.
2000-05-24  0:00       ` Robert Dewar
2000-05-24  0:00         ` David C. Hoos, Sr.
2000-05-24  0:00           ` Ted Dennison
2000-05-24  0:00             ` Robert Dewar
2000-05-24  0:00           ` Robert Dewar
2000-05-23  0:00     ` Robert Dewar
2000-05-23  0:00       ` Ted Dennison
2000-05-23  0:00         ` Robert Dewar
2000-05-23  0:00           ` Ted Dennison
2000-05-24  0:00             ` Robert Dewar
replies disabled

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