[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];
}
else
...
}
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.
David
More information about the cfe-dev
mailing list