MiguelC
MiguelC

Reputation: 308

Are classes structs or struct pointer

If I'm not mistaken, structs mean objects, and struct pointers mean pointer to objects right? In an article, It says that classes are structs which means that they are objects.

Filter the list of all classes
The traditional definition of a class in Objective-C looks like this:

struct objc_class {
    Class isa;
    Class super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
    };

So, if it says that classes are structs, then how will they fit in the argument of objc_msgSend(id self, SEL_cmd) which requires a struct pointer which is of type id?

Upvotes: 4

Views: 1709

Answers (2)

Gabriele Petronella
Gabriele Petronella

Reputation: 108111

Classes are structs, but Class is a pointer type, being defined as

typedef struct objc_class *Class;

and this answers the first part of the question.

Now, if you take a look at <objc/objc.h> you'll find

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

 #if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

and in <obj/runtime.h> you'll find

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

meaning that in Objective-C 2.0 objc_object and objc_class are identical structs, both having an isa field.

That's why you can pass a Class where an id is required: classes are objects after all.

You would normally expect a warning about the incompatible pointers type, but apparently the Obj-C compiler uses an ad-hoc treatment this specific case. I have no references to support this, though.

EDIT

I finally found a reference in the clang source code:

In ASTContext.cpp, this is the Class declaration

TypedefDecl *ASTContext::getObjCClassDecl() const {
  if (!ObjCClassDecl) {
    QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0);
    T = getObjCObjectPointerType(T);
    TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T);
    ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
                                        getTranslationUnitDecl(),
                                        SourceLocation(), SourceLocation(),
                                        &Idents.get("Class"), ClassInfo);
  }
  
  return ObjCClassDecl;
}

and this is the id declaration

TypedefDecl *ASTContext::getObjCIdDecl() const {
  if (!ObjCIdDecl) {
    QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
    T = getObjCObjectPointerType(T);
    TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T);
    ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
                                     getTranslationUnitDecl(),
                                     SourceLocation(), SourceLocation(),
                                     &Idents.get("id"), IdInfo);
  }
  
  return ObjCIdDecl;
}

In both cases the type is set to the result of getObjCObjectPointerType. This causes the compiler to consider both Class and id as pointers to Objective-C objects.

Upvotes: 9

user529758
user529758

Reputation:

If I'm not mistaken, structs mean objects, and struct pointers mean pointer to objects right?

Mostly, yes. But since in Objective-C, objects (including classes) can only be manipulated using pointers, the shorthand "object" is used instead of a more correct "pointer to an object", even in pieces of official documentation.

So, if it says that classes are structs, then how will they fit in the argument of objc_msgSend()?

They pass a pointer to a struct which is an object. Class is a typedef for struct objc_class *, whereas id is a typedef for struct objc_object *. Both are (non-function) pointers, and both structures contain an isa field, they can be used interchangeably as far as you know what you are doing.

Upvotes: 5

Related Questions