Re: Advice needed about a possible bug in NSMethodSignature or NSInvocation
Re: Advice needed about a possible bug in NSMethodSignature or NSInvocation
- Subject: Re: Advice needed about a possible bug in NSMethodSignature or NSInvocation
- From: Chris Kane <email@hidden>
- Date: Wed, 10 Mar 2004 13:26:12 -0800
On Mar 10, 2004, at 10:08 AM, Thomas Lachand-Robert wrote:
Le 10 mars 04, ` 16:49, Chris Kane a icrit :
On Mar 3, 2004, at 4:39 PM, Thomas Lachand-Robert wrote:
The small test program below do exactly that, it calls two methods
with equal return type, one declared as (NSObject<NSCopying>*) and
the other as (Copy*) after a "typedef NSObject<NSCopying> Copy". No
problem with a standard call, but I get the following output for a
call via an NSInvocation:
Signature for method 'test1' = @, result address = 0x9a004.
Signature for method 'test2' = ^{NSObject=#}, result address =
0x30d510.
You get different results because the two type signatures created by
the compiler mean different things. Check out the typedef of 'id' in
the /usr/include/objc/objc.h: a pointer to a struct containing a
pointer to a class. Basically, id ('@') is a special case meaning
object, in interpreting the types, and pointer-to-Class[-pointer] or
pointer-to-struct-containing-Class[-pointer]-as-first-member are
handled more literally.
This is probably because you are separating the pointer from the type
declaration. You are returning Copy *, which means that in that
particular case you are returning a pointer to a Copy but in other
cases you might use Copy without using a pointer to it. I think the
behavior here is arguably correct, without too much effort, or if
not, the That's Just The Way It Works Principle would apply.
Try changing this:
typedef NSObject<NSCopying> Copy;
to this:
typedef NSObject<NSCopying> *Copy;
and change uses of Copy.
Thanks a lot for your answer, but I have to disagree there. Usually in
C "typedef SomeType SomeName" has the same effect than "#define
SomeName SomeType". For instance "typedef NSObject Object" is the same
than "#define Object NSObject".
Your suggestion implies it should be correct to have a different
behavior with something like NSObject<NSCopying>.
Maybe it was not clear in my first message, but the problem comes ONLY
from the protocol; that is "typedef NSObject Copy" causes no problem
at all. (I don't do that usually, but I tried in my test case.) So I
don't understand how this can be related to the definition of id in
/usr/include/objc/objc.h. BTW the compiler don't complain, and the
behavior of all other parts of the program is as expected. ONLY
NSInvocation is implied.
The point I was trying to make is that the compiler produces a '@'
typecode in a method signature through a special case, from pattern
recognition. When you typedef the type of the object separate from the
pointer to that object type, the pattern recognition doesn't seem to
apply.
For example, if you change:
typedef NSObject<NSCopying> Copy;
- (Copy *)test2 {....}
to:
typedef NSObject<NSCopying> * Copy;
- (Copy)test2 {....}
then the compiler does produce '@' again, for the return type of
-test2. Why? Must be some sort of type+pattern recognition. Remember
that 'id' contains the pointer within it; putting the pointer in the
typedef makes your typedef "more like" id. When the pointer is in the
type, things work. They don't work as in your case where you've
typedef'd the base type and left the pointer until the declaration. Or
to look at things another way...
Why does "NSObject *" produce a typecode of '@', instead of
'^NSObject'? Must be some sort of logic where the compiler says, "Is
'NSObject' an ObjC class I've seen declared?" and converts the NSObject
* to '@' in the typecode.
In your specific case, something about the protocol being in there must
be confusing things in the compiler just a bit too much. File a bug to
let the compiler folks at Apple know about the problem, but you'll have
to do something else than What You Want for the forseeable future.
But on the other hand, I don't think the compiler should be converting
everything which happened to look like a 'id' to '@' in the typecodes.
For example, if I have:
typedef struct mystruct {
struct objc_class *aClass;
} mystruct_t;
- (mystruct_t *)test3 {....}
I would not expect to see the typecode for the return value of -test3
show up as '@'. [I haven't tried it.]
About your remark on Copy* different from Copy, I just don't get it:
does returning NSObject* means that you can sometimes use NSObject
without using a pointer to it?
Well, 'NSObject' behaves as a type in its own right, but that doesn't
mean you can use it directly. The language disallows class types from
occurring in contexts where the definition would be 'inlined' (as a
type of a struct field, or on the stack, or ...), which is a constaint
of the language. But if NSObject wasn't a type, you couldn't do
"typedef NSObject MyType;".
Chris Kane
Cocoa Frameworks, Apple
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.