[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [objc-improvements] Just remembered something about multiple method
From: |
David Ayers |
Subject: |
Re: [objc-improvements] Just remembered something about multiple method signatures... |
Date: |
Sat, 06 Sep 2003 09:54:17 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 |
Ziemowit Laski wrote:
I guess my point is that arbitrarily picking a signature out of a pool
of contenders is fraught with problems, and I still believe that
the IMP fallback is a cleaner solution in this case. I don't think
doing this breaks (codegen-wise) the counterexample you guys keep
discussing (i.e., where all the candidate methods return
NSComparisonResult),
does it?
It doesn't on my architecture and probably not on the G4, but it would
on 64 bit archs where small enums (i.e. NSComparisionResult) are not the
same size as id (I'm not sure how the G5 handles small enums). In fact
it would probably turn into an outright compile time error. I just
liked that example because it wasn't constructed. (i.e. NSDate,
NSString and NSNumber have different prototypes for '-compare:'.)
But maybe I can offer a more constructed example based on the promotions
caused by IMP that shows the issue on all architecures and that given
the intensive use of float with NSView subclasses in OPENSTEP
derivatives, make it a valid one. I've attached an excerpt of a test
we're preparing for contribution.
Given
Class1: -(id)test1Float:(float)f int:(int)i;
Class2: -(Object *)test1Float:(float)f int:(int)i;
In the old case, you could get a warning about the compiler picking the
wrong prototype but the results were correct. But the new IMP promotion
for id typed receivers will promote them to doubles and clobber not only
of the float but all following arguments as well
I think that your suggestion about itteratively comparing the return
value and then the arguments before falling back to varadic processing
might be a good solution, as long as 'compatible' return
values/arguments are "merged" to a general type (such as id/class)
before falling back to varadic processing. (The warnings should remain,
and if you like, with a flag to turn them off :-) )
Cheers,
David
/* Test varadic promotions. */
/* Contributed by David Ayers <d.ayers@inode.at> */
/* fnear and dnear taken from previos tests. */
/* { dg-options "-lobjc" } */
/* { dg-do run } */
#include <objc/Object.h>
#include <limits.h>
extern void abort(void);
#define CHECK_IF(expr) if(!(expr)) abort();
#define FLT_VAL 3.1
#define INT_VAL 1
int
fnear (float x, float y)
{
float t = x - y;
return t == 0 || x / t > 1000000.0;
}
int
dnear (double x, double y)
{
double t = x - y;
return t == 0 || x / t > 100000000000000.0;
}
@interface Class1 : Object
-(id)test1Float:(float)f
int:(int)i;
-(void)test2Float:(float)f
int:(int)i;
@end
@implementation Class1
-(id)test1Float:(float)f
int:(int)i
{
if (i==1)
{
CHECK_IF (fnear(f, FLT_VAL));
CHECK_IF (i == INT_VAL);
}
else
{
printf("f:%f i:%i\n",f,i);
}
return nil;
}
-(void)test2Float:(float)f
int:(int)i
{
if (i==1)
{
CHECK_IF (fnear(f, FLT_VAL));
CHECK_IF (i == INT_VAL);
}
else
{
printf("f:%f i:%i\n",f,i);
}
}
@end
@interface Class2 : Object
-(Object *)test1Float:(float)f
int:(int)i;
-(void)test2Float:(double)f
int:(int)i;
@end
@implementation Class2
-(Object *)test1Float:(float)f
int:(int)i
{
if (i==1)
{
CHECK_IF (fnear(f, FLT_VAL));
CHECK_IF (i == INT_VAL);
}
else
{
printf("f:%f i:%i\n",f,i);
}
return nil;
}
-(void)test2Float:(double)f
int:(int)i
{
if (i==1)
{
CHECK_IF (dnear(f, FLT_VAL));
CHECK_IF (i == INT_VAL);
}
else
{
printf("f:%f i:%i\n",f,i);
}
}
@end
main()
{
Class1 *varClass1;
Class2 *varClass2;
id varId;
varClass1 = [Class1 new];
varClass2 = [Class2 new];
[varClass1 test1Float:FLT_VAL int: 1];
[varClass2 test1Float:FLT_VAL int: 1];
[varClass1 test2Float:FLT_VAL int: 1];
[varClass2 test2Float:FLT_VAL int: 1];
/* Passing non-1 will print values instead of asserting them.
But note that in some cases the second argumen will be
clobbered anyway. */
/* Regression: Could be fixed by selection/merge */
varId = varClass1;
[varId test1Float:FLT_VAL int: 2];
/* Regression: Could be fixed by selection/merge */
varId = varClass2;
[varId test1Float:FLT_VAL int: 2];
/* Either this will fail... */
varId = varClass1;
[varId test2Float:FLT_VAL int: 2];
/* ... or this will fail, depending on protoype selction. */
varId = varClass2;
[varId test2Float:FLT_VAL int: 2];
exit (0);
}
- [objc-improvements] Just remembered something about multiple method signatures..., Ziemowit Laski, 2003/09/05
- Re: [objc-improvements] Just remembered something about multiple method signatures...,
David Ayers <=
- Re: [objc-improvements] Just remembered something about multiple method signatures..., Chris Hanson, 2003/09/07
- Re: [objc-improvements] Just remembered something about multiple method signatures..., Ziemowit Laski, 2003/09/07
- Re: [objc-improvements] Just remembered something about multiple method signatures..., David Ayers, 2003/09/08
- Re: [objc-improvements] Just remembered something about multiple method signatures..., Ziemowit Laski, 2003/09/08
- Re: [objc-improvements] Just remembered something about multiple method signatures..., Pete French, 2003/09/09
- Re: [objc-improvements] Just remembered something about multiple method signatures..., Nicola Pero, 2003/09/09
- Re: [objc-improvements] Just remembered something about multiple method signatures..., David Ayers, 2003/09/09
- Re: [objc-improvements] Just remembered something about multiplemethod signatures..., Alexander Malmberg, 2003/09/08
- Re: [objc-improvements] Just remembered something about multiplemethod signatures..., Ziemowit Laski, 2003/09/08
- Re: [objc-improvements] Just remembered something about multiplemethod signatures..., Richard Frith-Macdonald, 2003/09/09