http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49301
--- Comment #1 from Nicola Pero <nicola at gcc dot gnu.org> 2011-06-06 15:14:24
UTC ---
> @class is used to tell the compiler the class exists, but that its not (yet)
> available. Eg: class B uses class A, but class A uses class B too, creating a
> recursive import, and thus goes wrong.
Yes, that's correct. Notice that there is no messaging involved in this
scenario. ;-)
An example would look like:
@class B;
@interface A
- (B *) giveMeB;
@end
@interface B
- (A *) giveMeA;
@end
without '@class B', the example doesn't compile because a method in
"@interface A" return "B *", which isn't known yet, and moving "@interface B"
before "@interface A" doesn't work because "@interface B" itself returns
"A *".
This is mostly a concern for header files.
> #import <objc/objc.h>
> #import <objc/Object.h>
>
> @class myClass;
>
> int main()
> {
> myClass *obj = [myClass new];
> }
>
> @interface myClass : Object
> @end
>
> @implementation myClass
> @end
This example is completely different. You are messaging 'myClass' which is
forward-declared, and the compiler can't determine if the class responds to
+new or not. ;-)
So, there is a problem with determining the correct method prototype, a
problem which wasn't obvious before because the compiler wasn't warning about
the problem ;-)
You can trivially fix it by moving "@interface myClass" before "int main()".
Note that both the recent Apple GCC and Apple clang emit a similar warning.
For example, compiling your code with clang produces:
> example.m:8:19: warning: receiver 'myClass' is a forward class and
> corresponding @interface may not exist
> myClass *obj = [myClass new];
> ^
> example.m:8:18: warning: method '+new' not found (return type defaults to
> 'id')
> myClass *obj = [myClass new];
> ^~~~~~~~~~~~~
>example.m:8:12: warning: unused variable 'obj' [-Wunused-variable]
> myClass *obj = [myClass new];
> ^
> 3 warnings generated.
So this warning is not specific to GCC. ;-)
By the way, the warning is useful, because when messaging a Class only declared
with a @class, the compiler is blind as to what messages it can accept, and
won't do any checks on method invocations. :-(
Thanks