comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: Equality operator overloading in ADA 83
Date: 1997/04/22
Date: 1997-04-22T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023680002204970006190001@news.ni.net> (raw)
In-Reply-To: 01bc4e9b$ac0e7fa0$72041dc2@lightning


In article <01bc4e9b$ac0e7fa0$72041dc2@lightning>, "Manuel Wenger"
<manuel@thunder.ch*> wrote:


>I've tried to overload the "=" operator for fractions in a package. It
>obviously doesn't work if the type isn't defined as "limited private", and
>I don't want that. As an alternative, I found out that I might as well do a
>renaming declaration, just by defining the type as "private" - so I've
>tried doing that as well, and then using the following to rename the equal
>sign:

In Ada 83, you aren't allowed to override the predefined equality operator
for nonlimited private types.

A bit of a bummer, and that's why they changed it for Ada 95.

Either you can make the type limited, and define the equality operator (and
a Copy operation, too, while you're at it), or, add an Is_Equal operation
and hope that clients remember to call that operation instead of "=".  Or,
if your type doesn't contain any access objects, you can leave the type as
nonlimited private, and use the technique below to make sure predefined
equality always works correctly.

In Ada 95, you can replace the equality operator for nonlimited types. 
However, there is a caveat, necessited by backwards compatibility issues. 
The issue is that, if the type is not a tagged type, and if an object of
the type is an component of a record or array, then the *predefined*
operator - not the overridden one - is called.  This is a real bummer.  

Note that if the type is tagged - even privately tagged - then the
overidden version is always called.

You can mitigate this issue 2 ways:

1.  Always make sure equality works, irrespecitive of whether the
predefined or overridden version is called.  

2.  Make the type privately tagged.

Note that this is a server problem, not a client problem.  You the
implementor of an abstraction are responsible for satisfying the contract
you advertised in the spec.

A client should never have to worry that if he declares a record or array
containing an object of your type, that equality won't work correctly.  You
the server must guarantee that equality always works.

For types with value semantics, that is, containing no components that are
access objects, then you can always make equality work, even predefined
equality.  You can do this with a bit of extra coding, or, just privately
tagging the type.

For types that have access object components, then you need to (privately)
inherit from Controlled to prevent structure sharing, so you're tagged
anyway, and the correct equality operator will get called.

Consider a type such as Bounded_String:

   type Bounded_String is private;
...
private

   type Bounded_String is
      record
         Buffer : String (1 .. Max_Length);
         Last    : Natural := 0;
      end record;

end;

The simplest technique is to just privately tag the type:

   type Bounded_String is
      tagged record
         Buffer : String (1 .. Max_Length);
         Last     : Natural := 0;
      end record;

If you don't want to do that, then you have to make sure that every Buffer
element has a known, default value.  When you shorten the logical length of
the Bounded_String, then you must assign the default value to the newly
unused Buffer elements:

   Default_Character : constant Character := Ada.Latin_1.Nul;

   type Bounded_String is
      record
         Buffer : String (1 .. Max_Length) := (others => Default_Character);
         Last : Natural := 0;
      end record;

For example, when you update a Bounded_String:

procedure Set (Bounded : in out Bounded_String; To : String) is
   Last : Natural renames Bounded.Last;
begin
   if To'Length >= Last then
      Bounded.Buffer (1 .. To'Length) := To;
   else
      declare
         Pad_Length : constant Positive := Last - To'Length;
         Pad : constant String (1 .. Pad_Length) := (others =>
Default_Character);
     begin
        Bounded.Buffer (1 .. Last) := To & Pad;
     end;
   end if;

   Last := To'Length;
end Set;

It took me a while to realize that, yes, even for types (without access
objects) that have a physical length greater than the logical length, you
can make the predefined equality work.  This is true even for Ada 83, so
you may be able to apply this technique to your problem.

I would like to take this opportunity - while I'm on my soapbox :-) - to
politely remind compiler vendors that they should make sure that equality
for Ada.Strings.Bounded.Bounded_String always works.  Either use some
compiler magic to make sure the overridden equality operator gets called,
privately tag Bounded_String, or implement the type using the technique
I've shown above.

You the purchaser of a compiler should test to make sure Bounded_String
works.  If the predefined equality is ever getting called, let your vendor
know his product is broken.  Perhaps this should be an ACVC test, too
(maybe it is already).

Matt

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




  reply	other threads:[~1997-04-22  0:00 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-04-21  0:00 Equality operator overloading in ADA 83 Manuel Wenger
1997-04-22  0:00 ` Matthew Heaney [this message]
1997-04-22  0:00   ` Philip Brashear
1997-04-22  0:00   ` Mats Weber
1997-04-22  0:00     ` Robert A Duff
1997-04-22  0:00       ` Matthew Heaney
1997-04-23  0:00         ` Mats Weber
1997-04-23  0:00           ` Robert A Duff
1997-04-24  0:00             ` Mats Weber
1997-04-24  0:00               ` Robert A Duff
1997-04-24  0:00                 ` Robert Dewar
1997-04-25  0:00                   ` Robert A Duff
1997-04-26  0:00                     ` Nick Roberts
1997-04-26  0:00                       ` Robert A Duff
1997-04-26  0:00                         ` Robert Dewar
1997-04-27  0:00                           ` Robert A Duff
1997-04-26  0:00                             ` Robert Dewar
1997-04-28  0:00                               ` Simon Wright
1997-04-29  0:00                                 ` Robert I. Eachus
1997-04-26  0:00                       ` Robert Dewar
1997-04-26  0:00                         ` Matthew Heaney
1997-05-02  0:00                           ` Nick Roberts
1997-05-04  0:00                             ` Robert Dewar
1997-05-05  0:00                               ` Robert A Duff
1997-05-05  0:00                               ` Mats Weber
1997-05-05  0:00                                 ` Robert Dewar
1997-05-06  0:00                                   ` Matthew Heaney
1997-05-06  0:00                                     ` Robert Dewar
1997-05-07  0:00                                     ` Tucker Taft
1997-04-29  0:00                       ` Mats Weber
1997-05-01  0:00                         ` Robert Dewar
     [not found]                           ` <01bc571c$01f3ffc0$5de2b8cd@p5120.bda>
1997-05-03  0:00                             ` Robert Dewar
1997-04-27  0:00                     ` Robert Dewar
1997-04-27  0:00                       ` Fergus Henderson
1997-04-27  0:00                         ` Robert Dewar
1997-04-28  0:00                           ` Fergus Henderson
1997-04-28  0:00                             ` Robert Dewar
1997-04-25  0:00                 ` Mats Weber
1997-04-25  0:00                 ` Kevin Cline
1997-04-25  0:00                   ` Robert A Duff
1997-04-25  0:00                   ` Mats Weber
1997-04-25  0:00                     ` Robert Dewar
1997-04-29  0:00                       ` Mats Weber
1997-05-01  0:00                         ` Robert Dewar
1997-04-25  0:00                   ` Mats Weber
1997-04-27  0:00                     ` Robert Dewar
1997-04-29  0:00                       ` Mats Weber
1997-04-27  0:00                 ` Geert Bosch
1997-04-24  0:00               ` Matthew Heaney
1997-04-25  0:00                 ` Robert Dewar
1997-04-25  0:00                   ` Matthew Heaney
1997-04-26  0:00                     ` Robert Dewar
1997-04-26  0:00                   ` Fergus Henderson
1997-04-26  0:00                     ` Robert A Duff
1997-04-26  0:00                       ` Robert Dewar
1997-04-27  0:00                     ` Robert Dewar
1997-04-25  0:00                 ` Robert Dewar
1997-04-25  0:00                   ` Matthew Heaney
1997-04-26  0:00                     ` Robert A Duff
1997-04-26  0:00                     ` Robert Dewar
1997-04-28  0:00               ` Robert Dewar
1997-04-28  0:00               ` Robert Dewar
1997-04-29  0:00                 ` Matthew Heaney
1997-05-01  0:00                   ` Robert Dewar
1997-04-29  0:00                 ` Mats Weber
1997-04-29  0:00                   ` Robert A Duff
1997-04-29  0:00                     ` Matthew Heaney
1997-05-02  0:00                       ` Tucker Taft
1997-05-02  0:00                         ` Robert Dewar
1997-05-02  0:00                           ` Robert A Duff
1997-05-03  0:00                             ` Robert Dewar
1997-05-01  0:00                   ` Robert Dewar
1997-04-23  0:00           ` Robert Dewar
1997-04-24  0:00             ` Robert A Duff
1997-04-29  0:00             ` Mats Weber
1997-05-01  0:00               ` Robert Dewar
1997-04-24  0:00         ` Robert Dewar
1997-04-22  0:00       ` Mats Weber
1997-04-22  0:00     ` Matthew Heaney
1997-04-23  0:00       ` Mats Weber
1997-04-23  0:00         ` Robert A Duff
1997-04-25  0:00           ` Kevin Cline
1997-04-25  0:00             ` Matthew Heaney
1997-04-25  0:00               ` Robert A Duff
1997-04-25  0:00                 ` Jon S Anthony
1997-04-27  0:00                   ` Robert Dewar
1997-04-28  0:00                   ` Robert I. Eachus
1997-04-29  0:00                     ` Jon S Anthony
1997-04-26  0:00               ` Robert Dewar
1997-04-27  0:00                 ` Matthew Heaney
1997-04-27  0:00                   ` Robert A Duff
1997-04-25  0:00             ` Robert A Duff
1997-04-26  0:00             ` Robert Dewar
1997-04-26  0:00               ` Matthew Heaney
1997-04-24  0:00     ` Robert Dewar
1997-04-24  0:00       ` Robert A Duff
1997-04-25  0:00         ` Robert Dewar
1997-04-25  0:00           ` Matthew Heaney
1997-04-26  0:00             ` Robert Dewar
1997-04-26  0:00               ` Robert A Duff
1997-04-26  0:00                 ` Robert Dewar
1997-04-26  0:00                   ` Matthew Heaney
1997-04-27  0:00                     ` Robert Dewar
1997-04-27  0:00                   ` Robert A Duff
1997-04-26  0:00                     ` Robert Dewar
1997-05-02  0:00                       ` Nick Roberts
1997-05-04  0:00                         ` Robert Dewar
1997-04-26  0:00                 ` Robert Dewar
1997-04-26  0:00                   ` Matthew Heaney
1997-04-27  0:00                   ` Robert A Duff
1997-04-22  0:00 ` Kevin Cline
1997-04-22  0:00   ` Mark A Biggar
1997-04-24  0:00   ` Keith Thompson
1997-04-22  0:00 ` Mats Weber
replies disabled

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