[cfe-dev] Comparison of pointers between Objc subclasses

Ted Kremenek kremenek at apple.com
Tue Jul 1 20:54:23 PDT 2008


On Jul 1, 2008, at 7:44 PM, Eli Friedman wrote:

> On Tue, Jul 1, 2008 at 4:22 PM, Ted Kremenek <kremenek at apple.com>  
> wrote:
>> Are pointer type compatibility checks for assignments and  
>> conversions being
>> handled in the same way?
>
> Assignment (from C99 6.5.16.1):
> One of the following shall hold:
> <snip>
> both operands are pointers to qualified or unqualified versions of
> compatible types, and the type pointed to by the left has all the
> qualifiers of the type pointed to by the right;
> <snip>
>
> Comparison (from C99 6.5.9):
> One of the following shall hold:
> <snip>
> both operands are pointers to qualified or unqualified versions of
> compatible types;
> <snip>
>
> And currently, we (inconsistently) consider ObjC base types and
> derived types compatible in the C99 sense, which is implemented in
> ASTContext::typesAreCompatible.

Thanks Eli.

C99 obviously doesn't stipulate the compatibility of pointers to  
Objective-C classes, which gets back to the original issue.  In this  
regards, C99 6.5.9 might not even apply when comparing Objective-C  
types ("compatibility" is defined by an extended type system that is  
well beyond the scope of C99).  This of course was the original  
issue.  Because there is a subclassing relationship here between  
NSArray and NSMutableArray (which is a subtyping relationship from a  
PL theory standpoint), it makes sense to me that the pointer types are  
compatible, but I'm not an Objective-C lawyer.

Incidentally, comparing a pointer to a derived type is with a pointer  
to a base type is okay in C++ (at least as far as C++ classes and g++ - 
pedantic is concerned; I'm not certain what the standard says):

  $ cat t.cpp

  class A {};
  class B : public A {};

  bool f(A* a, B* b) { return a == b; }

  $ g++ -pedantic -fsyntax-only t.cpp
  $

This example appears to be essentially the same as the one Thomas  
presented in his original email, except that we are dealing with C++  
classes, not Objective-C classes.  Incidentally, the following  
Objective-C example also passes with gcc -pedantic:

  $ cat t.m

  @interface A { int x; } @end
  @interface B : A { int y; } @end

  int f(A* a, B* b) {
    return a == b;
  }

  $ gcc -pedantic -fsytnax-only t.m
  $


If we remove the subtyping relationship between B and A, however, gcc  
issues a warning:

  $ cat t2.m

  @interface A { int x; } @end
  @interface B { int y; } @end

  int f(A* a, B* b) {
    return a == b;
  }

  $ gcc -fsyntax-only -pedantic t2.m
  t2.m: In function ‘f’:
  t2.m:5: warning: comparison of distinct Objective-C types lacks a cast
  $

Now lets look at assignments (t3.m is the same as t.m except the  
comparison is now an assignment).  Notice that B subclasses A:

  $ cat t3.m

  @interface A { int x; } @end
  @interface B : A { int y; } @end

   A* f(A* a, B* b) {
     return a = b;
   }

  $ gcc -pedantic -fsyntax-only t3.m
  $

What happens if we assign a to b (where B still subclasses A)?

  $ cat t4.m

  @interface A { int x; } @end
  @interface B : A { int y; } @end

   A* f(A* a, B* b) {
    return b = a;
   }

  $ gcc -pedantic -fsyntax-only t4.m
  t4.m: In function ‘f’:
  t4.m:5: warning: assignment from distinct Objective-C type

GCC's diagnostics are horrible, but I think this experiment  
illustrates that two Objective-C pointer types can be compared if one  
pointee subclasses the other (a subtyping relationship), and in an  
assignment two types are compatible if the type of the right  
expression subtypes the left expression.  This makes sense because B*  
can be treated as an A*, but an A* cannot always be treated as a B*  
(since B is more specialized, and that A* might actually be a C*,  
where C subclasses A, but is neither a parent or subclass of B).

So, I think the answers we are looking for are outside the letter of  
C99 standard.  The Objective-C and C++ object type systems are a  
completely different animal.



More information about the cfe-dev mailing list