| |||||||||||||||||||||||||||||
|
Hi, I am working on a logging package for C and Objective-C . To be able to keep syntax for logging macros the same in C functions and ObjC methods, I am trying to do: id myself = localVariableAvailable(self) ? self : NULL I tried to look at the first character of __FUNCTION__ and (if it is '+' or '-') call a combination of __builtin_return / __builtin_apply_args() to retrieve the first argument. This approach has two problems: 1. When used with -fomit-frame-pointer I had semi-reproducible crashes on x86_64 a method returns void. (gcc 4.0.1, OS X 10.5.1) 2. It doesn't work with methods returning structs, which is probably because I use a "fake" function (with a fixed return type) to be able to use __builtin_return. void *retself(void *self, void *_cmd) { return self; } void *getself(void *args) { __builtin_return( __builtin_apply((void (*)()) retself, args, 2 * sizeof(void*) ) ); } [for reference, my complete test code for OS X 10.5 is attached below] Can anyone think of a reliable approach to access "self" which will gracefully yield NULL when used outside a method ? Thanks for your time, kind regards, Bjoern --- 8< --- /* gcc -fomit-frame-pointer -Os -arch i386 -arch ppc -framework Foundation -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/ MacOSX10.4u.sdk -o arg-rel arg.m gcc -Os -arch x86_64 -arch ppc64 -framework Foundation -mmacosx- version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk -o arg-64- rel arg.m */ #include <stdio.h> #import <Foundation/Foundation.h> #define LP_ARGS __builtin_apply_args() #define LP_FUNC __PRETTY_FUNCTION__ void *retself(void *self, void *_cmd) { return self; } void *getself(void *args) { __builtin_return( __builtin_apply((void (*)()) retself, args, 2 * sizeof(void*) ) ); } void logger(const char *tag, id realself, void *args) { id fakeself = (*tag =='+' || *tag == '-') ? getself(args) : NULL; printf("%-40.40s: self: %p getself: %p\n", tag, realself, fakeself); if( realself != fakeself ) { fprintf(stderr, "FAIL !!!!\n"); / *exit(1);*/ } } void cFuncVoid(void) { logger(LP_FUNC, NULL, LP_ARGS); } int cFuncArgs(int a, int b) { logger(LP_FUNC, NULL, LP_ARGS); return a+b; } @interface ArgTest : NSObject - (float) xFromPoint: (NSPoint) p; - (NSRect) rectFromPoint: (NSPoint) p width: (float) width height: (int) height; - (void) nop; + (void) classNop; @end @implementation ArgTest - (float) xFromPoint: (NSPoint) p { logger(LP_FUNC, self, LP_ARGS); return p.x; } - (NSRect) rectFromPoint: (NSPoint) p width: (float) width height: (int) height { logger(LP_FUNC, self, LP_ARGS); return NSMakeRect(p.x,p.y,width,height); } - (void) nop { logger(LP_FUNC, self, LP_ARGS); } + (void) classNop { logger(LP_FUNC, self, LP_ARGS); } @end int main(int argc, char **argv) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; cFuncArgs(23,42); ArgTest *a = [[ArgTest alloc] init]; float x = [a xFromPoint: NSMakePoint(1.2,3.4)]; printf("x: %f\n", x); NSRect r = [a rectFromPoint: NSMakePoint(1.2,3.4) width: 5.6 height: 7.8]; printf("r: %s\n", [NSStringFromRect(r) UTF8String]); [a nop]; [ArgTest classNop]; /* had semi-reproducible crashes with -fomit- frame-pointer on x86_64 */ [pool release]; return 0; }
| ||||||||||||||||||||||||||||
© 2004-2008 readlist.com