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


Ziemowit Laski wrote:
On 15 Oct 2004, at 10.00, David Ayers wrote:

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.


Well if it is indeed /only/ forward-declared, then it will remain opaque. Yet if it is later declared (i.e. before the methods are used) I cannot see a reason why not to use the prototypes for code generation.



  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];


Absolutely agreed!



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.

This is not the case I'm worried about and not the case I'm trying to deal with. As you very well described, it is ambiguous and I view it as undefined behavior if a Class / object adopts protocols with incompatible signatures.


Let's try this example

@protocol MyProto1
- (const char *)name;
@end

@protocol MyProto2
- (NSString *)name;
@end

@interface MyRootClass <MyProto1>
@end

@interface OtherRootClass
@end

@interface MyClass : OtherRootClass <MyProto2>
@end

In this case <MyProto2> is not a protocol declared by a root class. Therefor we should not be falling back to the instance methods in the case of:

Class <Proto2> clsP2;
[clsP2 name]; /* may not respond */

and the case:

Class cls;
[cls name]; /* OK */

should not be ambiguous as there is only one prototype declared by MyProto1 which should be in the class hash table.

I am aware that in the first case above the compiler does fall back to /use/ the prototype from the class hash table of the second case, but the user has been warned, so that's fine. We do avoid using the instance signatures of MyProto2 incorrectly.

I'm less worried about the cases you described, where the fact that MyProto2 is first used as a non-root protocol and later found to be adopted by a root class. I think we should only use the information that we've seen up to the point where we need it.

Cheers,
David


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