Obtaining first argument in Objective C method without explicitly using self ?

Bjoern Kriews bkr@jumper.org
Fri Jan 25 15:20:00 GMT 2008


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;
}




More information about the Gcc-help mailing list