This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug objc/49301] Forward declaration of classes broken
- From: "nicola at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 6 Jun 2011 15:14:28 +0000
- Subject: [Bug objc/49301] Forward declaration of classes broken
- Auto-submitted: auto-generated
- References: <bug-49301-4@http.gcc.gnu.org/bugzilla/>
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