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 obje
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 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 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.
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(*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(*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.