[cfe-dev] Comparison of pointers between Objc subclasses

David Chisnall csdavec at swansea.ac.uk
Wed Jul 2 07:05:19 PDT 2008

On 2 Jul 2008, at 14:16, Jean-Daniel Dupas wrote:

> Le 2 juil. 08 à 12:58, David Chisnall a écrit :
>> On 2 Jul 2008, at 00:22, Ted Kremenek wrote:
>>> Are pointer type compatibility checks for assignments and  
>>> conversions
>>> being handled in the same way?  I can understand why assigning a  
>>> base
>>> type to a derived type is dangerous, but it seems to me that
>>> comparisons like these should be legal.  I'm only raising this point
>>> because the code snippet with the warning involved a comparison, not
>>> an assignment.
>> Comparisons between ObjC pointers should contain an implicit cast to
>> id.  I tweaked CodeGen to do this  and sent the patch a month or so
>> ago, but it wasn't an ideal solution since the problem is really in
>> Sema, and it only fixed a few cases where Sema was doing almost the
>> right thing but omitting the implicit cast.
> Wouldn't this implicit cast prevent the "comparison of distinct  
> Objective-C types lacks a cast" warning ?

No.  The warning is just a warning.  Objective-C type tags are  
informative, nothing more.  The type of an Objective-C object is a  
property of the object, not of the variable holding the object.  The  
warning says 'you think these two objects have different types, but  
you are still comparing them, are you sure that's sensible?'  The  
implicit cast should be inserted so that CodeGen will generate the  
correct code, rather than failing because you are comparing distinct  
pointer types.

The same is true of an assignment.  It is perfectly legal to assign  
any object pointer to any other object pointer in Objective-C, it just  
isn't usually sensible, which is why you get a warning.  In some  
situations, however, it is useful.  You might have something like this:

- (void) method:(A*)anObject
	if ([anObject isKindOfClass:[B class]])
		[self methodExpectingB:(B*)anObject];

This can be required because Objective-C objects have two types - the  
implicit type determined by their signature and their structural  
type.  The tag type carries both implicitly.  You can safely pass  
object B to something expecting A if it implements every method of A.   
You may also want to override a method which expects an A, and have a  
special case for objects of type B, which either accesses their  
instance variables directly, or uses some methods only present in B.   
Of course, this is better done with protocols, but that requires you  
to have access to the class which you are subclassing's source code.


More information about the cfe-dev mailing list