Grupy dyskusyjne Google nie obsługują już nowych postów ani subskrypcji z Usenetu. Treści historyczne nadal będą dostępne.

Equality on Ada.Strings.Unbounded

0 wyświetleń
Przejdź do pierwszej nieodczytanej wiadomości

Mats Weber

nieprzeczytany,
16 sty 1996, 03:00:0016.01.1996
do
!topic Equality on Ada.Strings.Unbounded
!reference RM95-A.4.5(4, 72, 83)
!from Mats Weber (e-mail: Mats....@elca-matrix.ch) 96-01-11
!keywords equality predefined unbounded string
!discussion

The type Ada.Strings.Unbounded.Unbouned_String is defined as private, and
nothing is said about its full implementation (private part of the package
Ada.Strings.Unbounded).

The function "=" on unbounded strings is redefined in the package. As the
type is just private, not tagged, its predefined "=" will reemerge in some
situations such as the following:

type Person is
record
Name, First_Name : Ada.Strings.Unbounded.Unbouned_String;
end record;

This will cause different behaviour on different implementations:

if the full representation of Unbouned_String is tagged, then equality on
Person will be the equality of the string values, as is probably wanted;

if the full representation of Unbouned_String is not tagged, then "="
(Person, Person) uses the predefined equality of the type Unbouned_String,
which will not work most of the time.

The reemergence of predefined equality also happens inside generics of the form

generic
type T is private;
...

when they are instantiated with T => Ada.Strings.Unbounded.Unbouned_String.

This situation can cause severe portability problems.

To solve the problem, I propose that the standard require that the full
definition of Ada.Strings.Unbounded.Unbouned_String be a tagged. (It was
so in a previous version of Ada 9X but got removed).

Variable length strings have been a shortcoming of Ada for 13 years now
and I think it would be sad to introduce new problems in that area in Ada
95.

(Message sent to ada-c...@sw-eng.falls-church.va.us and copied to
comp.lang.ada).

Mats Weber

Keith Thompson

nieprzeczytany,
17 sty 1996, 03:00:0017.01.1996
do
In <Mats.Weber-16...@mlma21.elca-matrix.ch> Mats....@elca-matrix.ch (Mats Weber) writes:
> !topic Equality on Ada.Strings.Unbounded
> !reference RM95-A.4.5(4, 72, 83)
> !from Mats Weber (e-mail: Mats....@elca-matrix.ch) 96-01-11
> !keywords equality predefined unbounded string
> !discussion
>
> The type Ada.Strings.Unbounded.Unbouned_String is defined as private, and
> nothing is said about its full implementation (private part of the package
> Ada.Strings.Unbounded).

[ Discussion of predefined vs. primitive "=" on Unbounded_String deleted ]

> To solve the problem, I propose that the standard require that the full
> definition of Ada.Strings.Unbounded.Unbouned_String be a tagged. (It was
> so in a previous version of Ada 9X but got removed).

Note that the full definition of Unbounded_String will probably be tagged
in most or all implementations (or at least have a tagged component,
which would also solve the problem). Since the RM forbids storage leaks
on assignment and scope exit (RM95-A.4.5(88), the obvious implementation
is as a controlled, and therefore tagged, type.

Unfortunately, there's also an explicit "=" operator
declared for type Bounded_String (in the generic package
Ada.Strings.Bounded.Generic_Bounded_Length). The obvious implementation
of Bounded_String is not tagged.

Are there any other types declared in language-defined packages with
explicitly declared "=" operators?

The question is, what happens when the "=" operator is applied to
a composite which contains components with their own "=" operators?
The Ada 95 RM says that the primitive (possibly user-defined) "=" is
applied for tagged components, but the predefined "=" is applied for
non-tagged components. This inconsistency is supposed to be for upward
compatibility; the rule could be safely changed for tagged types since
they don't exist in Ada 83. It seems to me, though, that the slight
incompatibility would have been better than the existing inconsistency.
It's hard to imagine existing Ada 83 code that deliberately depends on
the old behavior.

--
Keith Thompson (The_Other_Keith) k...@thomsoft.com (k...@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
Et tu, Barada Nikto?

Robert A Duff

nieprzeczytany,
18 sty 1996, 03:00:0018.01.1996
do
In article <4dlmr7$1i...@watnews1.watson.ibm.com>,
Norman H. Cohen <nco...@watson.ibm.com> wrote:
>This is a valid concern. Ada 83 at least had the safeguard that to give
>a type like Bounded_String its own "=" operator you had to make it
>limited.

True. But it would be pretty annoying if bounded and unbounded strings
could not be assigned. It's bad enough that you can't use string
literals and the syntax for indexing. Disallowing assignment would make
these types even more "second class".

Also, the problem occurs for all operators, not just for equality. For
example, "<" is predefined on arrays. But if you redefine "<" for the
component type, the "<" for the array type is not affected. If you
redefined "and" on a boolean type, then the "and" on an
array-of-that-boolean-type is not affected.

A similar problem occurs in generics. For a generic formal integer type
like "type T is range <>;", *inside* the generic, it uses the predefined
"+" operator, even if "+" has been redefined by the user for the actual
type.

It may be that people don't depend on these rules on purpose. However,
upward compatibility requires that you don't change the semantics of
working programs, even in cases where they work "by accident". We
considered fixing this problem in Ada 9X, and upward compatibility was
the main reason for not doing so. Another reason is that it's not
really clear how far one ought to go in that direction. For example, if
the user redefines "=" for an integer type, should case statements
change their behavior to match the new equality? Sounds like a lot of
trouble.

I agree that it would be nice for compilers to warn of these kinds of
cases.

I also agree that we exacerbated the problem by allowing "=" to be
redefined for non-limited types. I also agree that the original comment
in this thread points out a bug in the RM -- clearly, the semantics of
"=" for records containing Unbounded_Strings should not be
implementation dependent. (Note that a garbage-collected implementation
would not *need* to make Unbounded_String tagged just to avoid storage
leaks.)

- Bob

Norman H. Cohen

nieprzeczytany,
18 sty 1996, 03:00:0018.01.1996
do
In article <DLCEv...@thomsoft.com>, k...@thomsoft.com (Keith Thompson)
writes:

|> The question is, what happens when the "=" operator is applied to
|> a composite which contains components with their own "=" operators?
|> The Ada 95 RM says that the primitive (possibly user-defined) "=" is
|> applied for tagged components, but the predefined "=" is applied for
|> non-tagged components. This inconsistency is supposed to be for upward
|> compatibility; the rule could be safely changed for tagged types since
|> they don't exist in Ada 83. It seems to me, though, that the slight
|> incompatibility would have been better than the existing inconsistency.
|> It's hard to imagine existing Ada 83 code that deliberately depends on
|> the old behavior.

This is a valid concern. Ada 83 at least had the safeguard that to give


a type like Bounded_String its own "=" operator you had to make it

limited. That meant that any composite containing a Bounded_String
component would also be limited, so that if you wanted to compare two
values of the composite type for equality you would have to write an
explicit equality operator for the composite type. This was
inconvenient, but safe: There was no danger of implicitly invoking some
unwanted bitwise equality operator for Bounded_String.

(The typical implementation of Bounded_String is

type Bounded_String is
record
Current_Length : Integer range 0 .. Max_Length;
Contents : String (1 .. Max_Length);
end record;

and the corresponding implementation of "=" is

function "=" (Left, Right: Bounded_String) return Boolean is
begin
return
Left.Contents (1 .. Left.Current_Length) =
Right.Contents (1 .. Right.Current_Length);
end "=";

In contrast, the predefined "=" for a Bounded_String record would compare
all the characters in the Contents components for equality, not just
those up to the Current_Length, and could return False for two bounded
strings that were logically equal.)

I urge compiler writers to issue warnings whenever an equality test on
composites causes predefined "=" to be invoked for a component type that
has an explicitly declared "=".

--
Norman H. Cohen nco...@watson.ibm.com

Mats Weber

nieprzeczytany,
22 sty 1996, 03:00:0022.01.1996
do
>> To solve the problem, I propose that the standard require that the full
>> definition of Ada.Strings.Unbounded.Unbouned_String be a tagged. (It was
>> so in a previous version of Ada 9X but got removed).
>
>Note that the full definition of Unbounded_String will probably be tagged
>in most or all implementations (or at least have a tagged component,
>which would also solve the problem). Since the RM forbids storage leaks
>on assignment and scope exit (RM95-A.4.5(88), the obvious implementation
>is as a controlled, and therefore tagged, type.

OK, but the `probably' must go away for portability. Requiring the whole
type to be tagged is a little bit too much. One could also simply say that
Unbounded_String must be implemented in a way that ensures proper
extension of "=" to records and that it also works when Unbounded_String
is used as a generic parameter.

>Unfortunately, there's also an explicit "=" operator
>declared for type Bounded_String (in the generic package
>Ada.Strings.Bounded.Generic_Bounded_Length). The obvious implementation
>of Bounded_String is not tagged.

I should have looked at it. I think the same comment also applies. It is
simply too dangerous to allow predefined "=" to reemerge.

>The question is, what happens when the "=" operator is applied to
>a composite which contains components with their own "=" operators?
>The Ada 95 RM says that the primitive (possibly user-defined) "=" is
>applied for tagged components, but the predefined "=" is applied for
>non-tagged components. This inconsistency is supposed to be for upward
>compatibility; the rule could be safely changed for tagged types since
>they don't exist in Ada 83. It seems to me, though, that the slight
>incompatibility would have been better than the existing inconsistency.
>It's hard to imagine existing Ada 83 code that deliberately depends on
>the old behavior.

I second that. I can't believe that reemergence was removed in a version
of the draft RM (I cannot remember which) and then reintroduced later.

Mats Weber

nieprzeczytany,
22 sty 1996, 03:00:0022.01.1996
do
>It may be that people don't depend on these rules on purpose. However,
>upward compatibility requires that you don't change the semantics of
>working programs, even in cases where they work "by accident". We
>considered fixing this problem in Ada 9X, and upward compatibility was
>the main reason for not doing so. [...]

But Ada 95 did other changes that remove backward compatibility, for
instance in sliding array bounds in record aggregates. For example

type R is record
S : String(1 .. 5);
end record;

T : String(2 .. 6);

X : R;

X := R'(S => T);

raises constraint_error in Ada 83 but not in Ada 95. So a program that
relies on that must be modified. One may argue that this is a pathological
example, but I would consider a program that relies on the reemergence of
predefined operators just as pathological.

Robert Dewar

nieprzeczytany,
23 sty 1996, 03:00:0023.01.1996
do
Mats says:

:raises constraint_error in Ada 83 but not in Ada 95. So a program that


relies on that must be modified. One may argue that this is a pathological
example, but I would consider a program that relies on the reemergence of

predefined operators just as pathological.:

Actually the constraint_error case *is* different. Reread the Ada 9X
requirements document. A decision was explicitly made that removing
constraint errors in favor of doing something sensible was an allowable
incompatibility, so the language designers were free to make, for example,
the sliding change without having to make the pathological argument.

The emergence issue is different, there definitely are programs that
rely, at least from an efficiency point of view, on reemergence. We
certainly discussed this issue, and decided that making an incompatile
change here would be unwise (the compatibility argument was taken
very seriously in the design!)

Yes, you can second guess any of these decisions, but you can be pretty
sure they were not taken casually!


Robert A Duff

nieprzeczytany,
23 sty 1996, 03:00:0023.01.1996
do
In article <Mats.Weber-22...@mlma21.elca-matrix.ch>,

Mats Weber <Mats....@elca-matrix.ch> wrote:
>But Ada 95 did other changes that remove backward compatibility, for
>instance in sliding array bounds in record aggregates. For example
>...

Yes, that's correct. Of course, it's a judgement call to decide whether
the benefit of a given upward incompatibility is worth it. In general,
these decisions were made in a very conservative manner. In most cases,
it is highly unlikely that a program will run into a problem. In some
cases, it could happen, but it's easy to fix (e.g., there are some new
reserved words -- if you happen to have used one, no big deal, just fix
it). And in some cases, the upward incompatibility is more serious, but
was thought to be worth it (e.g. type Character now has 128 new
character literals -- this is likely to cause problems (in fact, I have
had to modify some Ada 83 code for this reason), but support for
standard 8-bit characters was considered absolutely essential).

[example deleted]


>raises constraint_error in Ada 83 but not in Ada 95. So a program that
>relies on that must be modified.

True. However, a program that raises C_E in this manner is almost
certainly incorrect. Certainly, you can construct a case that will
handle the exception, and do something useful, but that's highly
unlikely. It especially unlikely to happen by accident. In fact,
I'd bet that the new rule will fix more bugs than it causes.

>... One may argue that this is a pathological


>example, but I would consider a program that relies on the reemergence of
>predefined operators just as pathological.

It's not purely an issue of how "pathological" it is. The fact is, that
a program can accidentally work, while relying on the reemergence of
predefined operators, whereas in your C_E example, it is far less likely
to work by accident.

I certainly agree that reemergence of predefined ops is an annoying
language rule, but I think the decision to keep it that way, for upward
compatibility, was correct.

- Bob

Norman H. Cohen

nieprzeczytany,
24 sty 1996, 03:00:0024.01.1996
do
In article <Mats.Weber-22...@mlma21.elca-matrix.ch>,
Mats....@elca-matrix.ch (Mats Weber) writes:

|> I second that. I can't believe that reemergence was removed in a version
|> of the draft RM (I cannot remember which) and then reintroduced later.

It just sort of, well, reemerged. :-)

Tucker Taft

nieprzeczytany,
24 sty 1996, 03:00:0024.01.1996
do
Robert A Duff (bob...@world.std.com) wrote:

: ...
: I certainly agree that reemergence of predefined ops is an annoying


: language rule, but I think the decision to keep it that way, for upward
: compatibility, was correct.

Actually, I have heard an alternative proposal which seems attractive.
We made the split on reemergence between tagged and untagged, which
preserved upward compatibility. An alternative split would be between
record and non-record. Since record types are the main types
which introduce the possibility of uninitialized components,
they are the ones which have a significant concern with
using the user-defined equality operator.

Reemergence of predefined ops on scalar types should be considered
a *feature*, not a bug, in my view, since it is likely that generics
are written with implicit assumptions about the relationship between
+, -, *, etc. If user-defined ops came along with a declaration
like "type T is range <>" then a generic could end up doing some
really strange stuff, and you would end up with significantly more
dependence on the details of the generic body than seems desirable.
As a specific example, I would think that the generic package
Ada.Text_IO.Integer_IO might break badly if the operators didn't
work as expected.

Equality on record types is somewhat different. About the only assumptions
made are that X=X, and after Y := X, then X=Y.

If the user-defined equality on a record type truly replaced the
predefined one, in all contexts (as is the case now for tagged types),
I think we would have a somewhat cleaner situation (albeit less upward
compatible). Of course, hindsight is 20-20, and these days, it seems
much easier to get people to accept a few more incompatibilities than in
the "old" days...

: - Bob

-Tuck
--
-Tucker Taft s...@inmet.com http://www.inmet.com/~stt/
Intermetrics, Inc. Cambridge, MA USA

Jon S Anthony

nieprzeczytany,
27 sty 1996, 03:00:0027.01.1996
do

> Actually, I have heard an alternative proposal which seems attractive.
> We made the split on reemergence between tagged and untagged, which
> preserved upward compatibility. An alternative split would be between
> record and non-record. Since record types are the main types

>...


> I think we would have a somewhat cleaner situation (albeit less upward
> compatible). Of course, hindsight is 20-20, and these days, it seems
> much easier to get people to accept a few more incompatibilities than in
> the "old" days...

In a case such as this (which does indeed sound like a nice
alternative), is there any "machinery" in place that would allow such
a change to the language definition? Prior to the next full revision,
that is. I seem to recall some talk that seemed to kinda sorta
indicate that maybe this could be possibly done. :-)

/Jon
--
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
j...@organon.com


Robert Dewar

nieprzeczytany,
27 sty 1996, 03:00:0027.01.1996
do
Jon asks

"In a case such as this (which does indeed sound like a nice
alternative), is there any "machinery" in place that would allow such
a change to the language definition? Prior to the next full revision,
that is. I seem to recall some talk that seemed to kinda sorta
indicate that maybe this could be possibly done. :-)"

Technically there is no such machinery. In really important cases, e.g.
8-bit characters allowed in Ada 83, there are ways, but this is clearly
a marginal issue for which it is out of the question to change the
standard.


Dan Eilers

nieprzeczytany,
29 sty 1996, 03:00:0029.01.1996
do
j...@organon.com (Jon S Anthony) wrote:

> In a case such as this (which does indeed sound like a nice
> alternative), is there any "machinery" in place that would allow such
> a change to the language definition? Prior to the next full revision,
> that is. I seem to recall some talk that seemed to kinda sorta
> indicate that maybe this could be possibly done. :-)

I think what you are referring to is the ISO Technical Corrigendum
process (see the Instructions for Comment Submission in RM95, para 65).

The ISO rules for changing standards have reportedly been significantly
relaxed since Ada83, allowing significant changes between major revisions.
Perhaps someone can post the official details.

With Ada95 no longer a MIL standard, control of the language rests with ISO,
and pretty much anything is possible that ISO agrees with.

-- Dan Eilers

Scott Leschke

nieprzeczytany,
29 sty 1996, 03:00:0029.01.1996
do
j...@organon.com (Jon S Anthony) writes:

>In a case such as this (which does indeed sound like a nice
>alternative), is there any "machinery" in place that would allow such
>a change to the language definition? Prior to the next full revision,
>that is. I seem to recall some talk that seemed to kinda sorta
>indicate that maybe this could be possibly done. :-)

If there isn't there should be. I agree that this alternative does at
least sound preferable and one would hope that there would be some way
to update the standard should the majority of interested parties concur.
The normal language revision cycle is way too long. A much shorter
cycle needs to be instituted for integrating smaller, less sweeping,
language changes.

The Storage_Manager concept that Intermetrics has done as part of their
ODMG binding also comes to mind as a candidate for inclusion into the
standard.

As always, these are just my opinions and the probability is always
high that I'm full of it.

--
-----------------------------------------------------------------------
Scott Leschke..................................ph: 708-632-2786
Motorola, Inc.................................fax: 708-632-3145
Cellular Infrastructure Group...............email: lesc...@cig.mot.com

Robert Dewar

nieprzeczytany,
31 sty 1996, 03:00:0031.01.1996
do
Dan says

"The ISO rules for changing standards have reportedly been significantly
relaxed since Ada83, allowing significant changes between major revisions.
Perhaps someone can post the official details.

With Ada95 no longer a MIL standard, control of the language rests with ISO,
and pretty much anything is possible that ISO agrees with."

Actually I don't think it matters at all whether Ada is a MIL standard or
not, since the MOU that existed for Ada 83 made sure that the MIL standard's
interpretation tracked the ISO interpretation exactly.

As for the supposed relaxation of ISO rules, I also think this is quite
irrelevant, since in practice ISO WG9 has been able to make any changes
that it sees fit. The WG9 interpretations for Ada 83 that eliminated
Numeric_Error as an exception and allowed type Character to be 8 bits
are good examples of what I mean.

The limitations on change are not beaurocratic, they are in practice
limitations from WG9 itself. You will find the working group reluctant,
as it should be, to recommend major changes in mid-stream, so the case
for a change has to be very convincing, and there has to be clear
consensus.

The technical issue here has actually evolved into two issues in this
discussion.

1) should equality on Ada.Strings.Unbounded work "properly", when, say,
a field of this type is in a record?

2) should we follow Tuck's suggestion for generalizing this for all
types appearing as record components?

I think 2) is out of the question at this stage. We discussed the issue
during the design, and the compatibility argument seemed strong enough
to give a definite no to this and related suggestions. I see nothing
that would turn this definite no into a definite yes.

As for 1), this is definitely within the normal realm of WG9/ARG
deliberation, and I think it makes good sense to provide an interpretation
that says that the full type for Ada.Strings.Unbounded has to be tagged.

Note that such a requirement has exactly two semantic effects that are
observable, it causes this type to be passed by reference, and it makes
sure the "right" equality operation is always used.

It does *not* require that the actual implementation use a tagged type (after
all the actual implementation might be in assembler, where the concept of
tagged type is nonsense, i.e. the full declaration for Ada.Strings.Unbounded
might look like.

type Asm_Unbounded;
pragma Import (Asm_Unbounded);
type Unbounded is new Asm_Unbounded;

or even simply

pragma Import (Unbounded);

(I am sure the first is allowed, I am not quite sure about the second. Note
I am not saying that all implemenations will allow types to be imported
this way, but they could).

More realistically, an implementation could for example implement a pragma
pragma Compose_Equality (type), and apply this pragma in the private part
to type Unbounded.

Actually such a pragma is probably the cleanest way to make the general
language extension ...

Robert Dewar

nieprzeczytany,
1 lut 1996, 03:00:001.02.1996
do
Bob said

">Actually such a pragma is probably the cleanest way to make the general
>language extension ...

I wouldn't bother. If you want "=" to compose, say "tagged"."

Harumph! My version of Ada 95 does not allow tagged arrays, tagged
floats or tagged enumeration types. It is unnecessarily heavy, both
in source text overhead, and runtime overhead, to require the wrapping
of a type in a tagged record just because you want equality to work.


Robert A Duff

nieprzeczytany,
1 lut 1996, 03:00:001.02.1996
do
In article <dewar.823093736@schonberg>, Robert Dewar <de...@cs.nyu.edu> wrote:
>1) should equality on Ada.Strings.Unbounded work "properly", when, say,
> a field of this type is in a record?
...

>As for 1), this is definitely within the normal realm of WG9/ARG
>deliberation, and I think it makes good sense to provide an interpretation
>that says that the full type for Ada.Strings.Unbounded has to be tagged.

Well, number (1) represents a bug in the RM. I think most people would
agree. So, I'm pretty sure ARG will make a ruling on this point.
I agree that the above-mentioned interpretation is probably right.
(There's still the same question for Bounded, though. And I intend to
search the RM for the same bug occurring in any other packages.)

>or even simply
>
> pragma Import (Unbounded);
>
>(I am sure the first is allowed, I am not quite sure about the second.

Yes, the above is allowed, if the implementation allows it.

I doubt if most implementations will fully support imported types,
though!

>...Note


>I am not saying that all implemenations will allow types to be imported
>this way, but they could).
>
>More realistically, an implementation could for example implement a pragma
>pragma Compose_Equality (type), and apply this pragma in the private part
>to type Unbounded.

Right, that's more realistic. Or even just having the compiler
recognize the type name and treat is specially.

>Actually such a pragma is probably the cleanest way to make the general
>language extension ...

I wouldn't bother. If you want "=" to compose, say "tagged".

- Bob

Keith Thompson

nieprzeczytany,
1 lut 1996, 03:00:001.02.1996
do
In <DM2M6...@world.std.com> bob...@world.std.com (Robert A Duff) writes:
[...]

> Well, number (1) represents a bug in the RM. I think most people would
> agree. So, I'm pretty sure ARG will make a ruling on this point.
> I agree that the above-mentioned interpretation is probably right.
> (There's still the same question for Bounded, though. And I intend to
> search the RM for the same bug occurring in any other packages.)

I just did this. (The specifications of all the predefined units are
available in a single file, rmsource.ada; I just searched for '"="').

The types which have explicitly defined "=" operators are (using '<' and
'>' to denote a generic unit):

System.Address
Ada.Strings.Maps.Character_Set
Ada.Strings.Bounded.<Generic_Bounded_Length>.Bounded_String
Ada.Strings.Unbounded.Unbounded_String
Ada.Strings.Wide_Maps.Wide_Character_Set
Ada.Task_Identification.Task_ID

Of these, System.Address is probably the most troublesome; you
(almost) certainly don't want it to be a tagged type. On the other
hand, implementations do have some latitude to do funny things with
predefined units. On the gripping hand, it would be nice to make whatever
mechanism the implementation uses available to users for their own types.
On the other gripping hand (??), as Bob pointed out, users can always
declare their own types as tagged.

Robert Dewar

nieprzeczytany,
4 lut 1996, 03:00:004.02.1996
do
Keith said, worrying about composition of equality

"Of these, System.Address is probably the most troublesome; you
(almost) certainly don't want it to be a tagged type. On the other
hand, implementations do have some latitude to do funny things with
predefined units. On the gripping hand, it would be nice to make whatever
mechanism the implementation uses available to users for their own types.
On the other gripping hand (??), as Bob pointed out, users can always
declare their own types as tagged."

Now let's not go over-board, in practice, the predefined equality will
work fine for Address, so your concern here is purely academic.


Robert Dewar

nieprzeczytany,
6 lut 1996, 03:00:006.02.1996
do
Keith said

"As Robert and I have discussed in email, it's probably impractical or
impossible to solve this in the implementation of the "=" operator.
Note, however, than an Ada access value (or System.Address) is not so
much a pointer as an abstraction of a pointer. The solution is to ensure
that the abstraction doesn't allow pathological cases. In other words,
guarantee that no non-erroneous program can generate two logically equal
pointers (access values, addresses, whatever) that aren't bitwise equal.
If you get such pointers from an outside source (e.g., by interfacing
to another language), that's too bad. I'm not familiar enough with the
use of segmented architectures to know whether this is a real problem."

This is getting *very* confused. Let's try to sort it out!

In Ada, there can be two equality operations for a given type, the
predefined equality operation, and possibly an explicitly defined
equality. What we are talking about here is the possible reemergence
of the predefined equality operation.

The whole business of bitwise comparison is a complete red herring. It is
true for some types that predefined equality may correspond to bitwise
equality, and if a composite object contains ONLY such types, then, since

with the exception of tagged types, predefined equality reemerges fr
composite equality, you can use biwise comparisons for the entire
composite.

But this is an implementation detail which is irrelevant to the semantic
discussion that started this thread (see the subject line!). There are in
fact cases now where the predefined equality cannot be done with bitwise
equality tests (e.g. floating-point with signed zeroes), so it is not
the case that bitwise equality can always be used for records and
arrays in any case.

We know we have a potential problem with Unbounded_String, and someone
asked what other siilar problems we have in the library. Keith picked
up System.Address as an example, but this is bogus. No equality
operation is defined on System.Address in package System, so the
equality operation that applies to this type is always the predefined
equality operation.

Even if we did have an architecture with pointer punning requiring complex
tests for pointer equality, these tests would have to be done all the time
in all contexts anyway, so under no conditions is System.Address an
instance of the same kind of worry that started this thread.

To answer the question of whether there are other types that have this
worry, you must look for types visible in the predefined packages for
which a defined equality operation is also visible. System.Address is
not such an example.


Robert A Duff

nieprzeczytany,
6 lut 1996, 03:00:006.02.1996
do
In article <DMC3E...@thomsoft.com>, Keith Thompson <k...@thomsoft.com> wrote:
>In <dewar.823456843@schonberg> de...@cs.nyu.edu (Robert Dewar) writes:
>In practice, that's probably true. My concern is for an implementation
>that declares System.Address as an integer type on a system with segmented
>addresses. On such a system, it's possible for two addresses to be
>logically equal (i.e., to refer to the same memory location) without
>being bitwise equal.

From a language point of view, this seems like a non-issue. Type
Address is inherently implementation dependent, and I really don't mind
having implementers decide whether equality on addresses composes
"properly".

Actually, I think that if I were implementing Ada on a segmented
machine, I would make "=" do bit-wise compare, and let the programmer
worry about the fact that two addresses might represent the same
location.

Anyway, segmented machines are falling out of favor. The 386
architecture is segmented, but all modern 386 operating systems ignore
the segmentation features -- they put everything in a single
32-bit-addressable segment, so it ends up looking like a non-segmented
machine.

>This is similar to the problem of "=" for record types, particularly
>record types whose representation includes gaps. One solution is to
>zero-fill the record when it's created, so that bitwise equality works.
>Another is to do component-by-component comparison, skipping over
>the gaps. In practice, I think record equality comparisons are rare
>enough that the latter approach is better.

The bit-wise approach doesn't work if the record contains floating point
components, and signed zeros are supported, because plus zero equals
minus zero in Ada, but they are represented with different bit patterns.
(Coincidentally, I was just discussing that issue with Robert Dewar.)

Record equality is probably rare for most records, but I would like it
to be efficient in *some* cases -- type Complex, for example. But I
suppose both techniques boil down to the same machine code anyway, for
type Complex, since there are probably no gaps.

- Bob

Keith Thompson

nieprzeczytany,
6 lut 1996, 03:00:006.02.1996
do
In <dewar.823456843@schonberg> de...@cs.nyu.edu (Robert Dewar) writes:
> Keith said, worrying about composition of equality
> "Of these, System.Address is probably the most troublesome;
> [...]

> Now let's not go over-board, in practice, the predefined equality will
> work fine for Address, so your concern here is purely academic.

In practice, that's probably true. My concern is for an implementation


that declares System.Address as an integer type on a system with segmented
addresses. On such a system, it's possible for two addresses to be
logically equal (i.e., to refer to the same memory location) without
being bitwise equal.

As Robert and I have discussed in email, it's probably impractical or


impossible to solve this in the implementation of the "=" operator.
Note, however, than an Ada access value (or System.Address) is not so
much a pointer as an abstraction of a pointer. The solution is to ensure
that the abstraction doesn't allow pathological cases. In other words,
guarantee that no non-erroneous program can generate two logically equal
pointers (access values, addresses, whatever) that aren't bitwise equal.
If you get such pointers from an outside source (e.g., by interfacing
to another language), that's too bad. I'm not familiar enough with the
use of segmented architectures to know whether this is a real problem.

This is similar to the problem of "=" for record types, particularly


record types whose representation includes gaps. One solution is to
zero-fill the record when it's created, so that bitwise equality works.
Another is to do component-by-component comparison, skipping over
the gaps. In practice, I think record equality comparisons are rare
enough that the latter approach is better.

--

Robert Dewar

nieprzeczytany,
6 lut 1996, 03:00:006.02.1996
do
Bob Duff says he does not mind having implementors decide on whether
equality for addresses composes properly in records.

I mind, the RM unconditionally requires that it compose properly!
Bob if you disagree with this tell me why. Note that there is no
equality operation for type address explicitly declared in package
System.


Robert Dewar

nieprzeczytany,
7 lut 1996, 03:00:007.02.1996
do
Robert Dewar said

Robert Dewar replies (!)

Hmmm! that must be other Robert Dewar, the one who knows Ada 83, but has
not carefully read the Ada 95 RM.

In fact the above statement is true of the Ada 83 RM, but false of the
Ada 95 RM. Someone snuck in a definitin of '=' for Address, which was
a quite unnecessary non-upwards compatible change. Quite unnecessary
because you cannot find any architecture on which the predefined
equality is inappropriate for address and thus it was trying to
solve a non-existent problem. Non-upwards compatible since it indeed
means that from a theoretical point of view, comparison of addresses
does not compose (which it did in Ada 83).

GRRR! Who put this in? Oh well, I should have noticed it earlier. In
any case it is a goof that the ARG will have to fix. Of course it is
still only an academic issue, since in practice the primitive equality
will be the same as the explicit equality, but the ARG is in the business
of addressing academic issues like this :-)


Keith Thompson

nieprzeczytany,
7 lut 1996, 03:00:007.02.1996
do
In <dewar.823614383@schonberg> de...@cs.nyu.edu (Robert Dewar) writes:

[ ... mostly stuff I agree with, but ... ]

> The whole business of bitwise comparison is a complete red herring. It is
> true for some types that predefined equality may correspond to bitwise
> equality, and if a composite object contains ONLY such types, then, since
> with the exception of tagged types, predefined equality reemerges fr
> composite equality, you can use biwise comparisons for the entire
> composite.

Unless there are gaps between the components; in that case the
implementation must either skip the gaps on comparison or initialize
them, probably to zero. Yes, this is a very minor nitpick.

> But this is an implementation detail which is irrelevant to the semantic
> discussion that started this thread (see the subject line!). There are in
> fact cases now where the predefined equality cannot be done with bitwise
> equality tests (e.g. floating-point with signed zeroes), so it is not
> the case that bitwise equality can always be used for records and
> arrays in any case.

Agreed.

> We know we have a potential problem with Unbounded_String, and someone
> asked what other siilar problems we have in the library. Keith picked
> up System.Address as an example, but this is bogus. No equality
> operation is defined on System.Address in package System, so the
> equality operation that applies to this type is always the predefined
> equality operation.

Um, that turns out not to be correct. See RM95-13.7(14):

function "=" (Left, Right : Address) return Boolean;

(A comment after this declaration points out that "/=" is implicitly
defined.)

> Even if we did have an architecture with pointer punning requiring complex
> tests for pointer equality, these tests would have to be done all the time
> in all contexts anyway, so under no conditions is System.Address an
> instance of the same kind of worry that started this thread.

There could be a problem under the following circumstances:

Pointer equality is not equivalent (on the machine level) to integer
equality.
System.Address is not declared as an access type (so the predefined
"=" doesn't quite work properly).
The declared "=" for System.Address does work properly (if it doesn't,
that's another problem).

Then the incorrect predefined "=" for System.Address will reemerge in the
"=" operator for a composite type with components of type System.Address.
A possible fix at the implementation level would be to declare
System.Address as an access type (if addresses and access types are
represented the same way), or perhaps to apply an implementation-defined
pragma to it.

In practice, of course, on most systems bitwise comparison (or at least
integer comparison) works just fine for addresses. Even on systems where
it doesn't (with certain kinds of segmented addressing, for example),
it's probably difficult or impossible to generate two addresses that are
logically equal and bitwise unequal without doing something erroneous,
and again predefined "=" works correctly. So, on almost all systems,
predefined and primitive "=" for System.Address are essentially identical,
and there is no problem.

Robert A Duff

nieprzeczytany,
8 lut 1996, 03:00:008.02.1996
do
In article <DME7r...@thomsoft.com>, Keith Thompson <k...@thomsoft.com> wrote:
>In <dewar.823614383@schonberg> de...@cs.nyu.edu (Robert Dewar) writes:
>Um, that turns out not to be correct. See RM95-13.7(14):
>
> function "=" (Left, Right : Address) return Boolean;

Even if this declaration were not there, it would *still* be
implementation dependent whether equality on Address composes,
because an implementation is allowed to put anything it wants
in package System.

I can't get too excited by non-portability of operations on type
Address.

- Bob

Robert Dewar

nieprzeczytany,
8 lut 1996, 03:00:008.02.1996
do
Keith says:

" Pointer equality is not equivalent (on the machine level) to integer
equality.
System.Address is not declared as an access type (so the predefined
"=" doesn't quite work properly).
The declared "=" for System.Address does work properly (if it doesn't,
that's another problem).

Well yes, but the number of architectures on which one can imaine this
set of circumstances actually occuring is apporxiately zero.

I agree this is a bug in the RM which should be fixed, but, like the bug
in Ada 83 that eliminated almost all static subtypes accidentally, it is
of academic interest only, not something that will affect anyone.

Note incidentally that if you are being really strict, the meaning of
address equality is undefined in the RM anyway, so it could for example
be non-deterministic!

Yes of course that's ludicrous from a pragmatic point of view, but then
from a pragmatic point of view, this whole discussion about equality on
address is irrelevant :-)


Robert A Duff

nieprzeczytany,
9 lut 1996, 03:00:009.02.1996
do
In article <dewar.823725025@schonberg>, Robert Dewar <de...@cs.nyu.edu> wrote:
>GRRR! Who put this in?

Me.

- Bob

Mats Weber

nieprzeczytany,
9 lut 1996, 03:00:009.02.1996
do
In article <DM2tn...@thomsoft.com>, k...@thomsoft.com (Keith Thompson) wrote:

>The types which have explicitly defined "=" operators are (using '<' and
>'>' to denote a generic unit):
>
> System.Address
> Ada.Strings.Maps.Character_Set
> Ada.Strings.Bounded.<Generic_Bounded_Length>.Bounded_String
> Ada.Strings.Unbounded.Unbounded_String
> Ada.Strings.Wide_Maps.Wide_Character_Set
> Ada.Task_Identification.Task_ID

Why not remove the redefinition of function "=" (Address, Address) in System ?

Nowe wiadomości: 0