[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ANN: libobjc2 1.1
From: |
Jens Ayton |
Subject: |
Re: ANN: libobjc2 1.1 |
Date: |
Thu, 13 Jan 2011 23:00:36 +0100 |
On Jan 13, 2011, at 22:36, David Chisnall wrote:
> On 13 Jan 2011, at 21:23, Jens Ayton wrote:
>>
>> * Unless you're calling a method which takes no parameters and returns an
>> object, it is necessary to typecast objc_msgSend to the appropriate
>> signature, and you can't cast a statement expression. The ... is just there
>> to confuse and frustrate people. Any working use of objc_msgSend() except
>> trivial test cases won't work with a macro implementation.
>
> Actually, that's not true. The IMP type is variadic, so you can call it with
> any arguments following the selector and it will work correctly and the
> compiler will generate exactly the same call frame as it would with an
> explicit cast.
Actually, it is true. :-)
In Apple-runtime compilers, at least, while IMP is declared variadic actual
method implementations are not. The calling conventions for variadic arguments
can be, and are, different than for non-variadic ones. In the following
example, the first two invocations produce the expected result ("1, 2, 3, 4")
while the third fails in different ways for i386 and x86_64 (it works on PPC):
+ (void) test:(int)a :(char)b :(float)c :(double)d
{
printf("%i, %i, %g, %g\n", a, b, c, d);
}
@end
int main (int argc, const char * argv[])
{
int a = 1;
char b = 2;
float c = 3;
double d = 4;
[Test test:a :b :c :d];
typedef void (*TestIMP)(id self, SEL _cmd, int a, char b, float c, double
d);
((TestIMP)objc_msgSend)([Test class], @selector(test::::), a, b, c, d);
objc_msgSend([Test class], @selector(test::::), a, b, c, d);
return 0;
}
The need to cast objc_msgSend is conveniently documented in the legacy document
Universal Binary Programming Guidelines, Second Edition, pp. 47-48.
--
Jens Ayton