discuss-gnustep
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]