This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Enhancing ObjC message lookup in the presence of protocols


On 15 Oct 2004, at 10.00, David Ayers wrote:
We don't artificially constrain marking forward declared protocols, but
mark all protocols adopted by root classes.  And insure the class hash
is filled with the corresponding methods.  Then we also insure this is
done for inherited protocols of root protocols.

I'm with you as far as putting these in the hash table. I'm also willing
to go along with specially marking protocols that are adopted (directly
or indirectly) by root classes, but not yet defined, so that we may inject
their methods into said hash table later. The reason I say "go along" is
that one could plausibly view a forward-declared (but not yet defined)
protocol as _intentionally_ opaque.


  So now we have the
"protocols adopted by root classes" marked, and we can use that
information during method lookup, do constrain the 'Class <Proto>'
lookup only to those marked protocols.  And now we're not only
potentially a tad bit faster but also more correct in the sense that we
reduce the potential of finding bogus cases of conflicting protocols!

And this is where you lose me. :-( If you have


   @protocol Proto1
     - (const char *) message;
     + (int) value;
   @end

   @protocol Proto2
     - (NSString *) message;
     + (float) value;
   @end

   id    <Proto1, Proto2> idP1P2;
   Class <Proto1, Proto2> clsP1P2;

then the following four message sends below are _all_ inherently ambiguous:

   [idP1P2 message];
   [idP1P2 value];
   [clsP1P2 message];
   [clsP1P2 value];

The reason they are inherently ambiguous is because the Proto1 and Proto2
make mutually inconsistent claims about method signatures, and it is not really
possible to have a class that satisfies both protocols! In other words, there
is no such thing as 'bogus cases of conflicting protocols' -- all such cases
are real, and indicate an inconsistent set of assumptions about the 'idP1P2' and
'clsP1P2' objects above.


Your proposal is to leverage additional information, such as

  @interface Root <Proto1>
  @end

to infer that '[clsP1P2 message]' refers to '- (const char *) message' (BTW,
would you make the same argument wrt '[idP1P2 message]', thereby changing
existing behavior?). However, just because you haven't seen a


  @interface Root2 <Proto2>
  @end

or, for that matter,

  @implementation Root3
  - (NSString *)message { .... }
  @end

does not mean that they do not exist in some translation unit making up your
program. Far from making your message dispatch 'more correct', you are lulling
yourself into a false sense of correctness by selectively ignoring conflicts
that the ObjC type system (FWIW :-) ) shows you are there.


It's really not that big of step and makes the whole search consistent.

It is not only inconsistent as far as lookup of class vs. instance methods
is concerned, it will also be inconsistent wrt lookup of instance methods
for the 'id <Proto1, Proto2>' case. Do you also only want to search Proto1
in that case, on the grounds that the Root class adopts it?


Actually I'm only concerned about:

(diff between my version and your version of class-protocol-1.m):
   { /* Class <protocol>, id */
-    obj == clsP1;
-    clsP1 == obj;
+    obj == clsP1; /* { dg-warning "lacks a cast" } */
+    clsP1 == obj; /* { dg-warning "lacks a cast" } */

   { /* Class <protocol>, id */
-    obj = clsP1;
-    clsP1 = obj;
+    obj = clsP1; /* { dg-warning "incompatible" } */
+    clsP1 = obj; /* { dg-warning "incompatible" } */

As I believe an unadorned 'id' should always be legal

Oooh, you are absolutely correct here; my bad. I'll fix it.


Thanks for your patience,

--Zem


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]