[Drawkit] DKGuide position mayhem
Graham Cox
graham.cox at bigpond.com
Sun Jun 22 21:00:57 PDT 2008
This is good advice, but in fact the issue is more subtle than just a
missing prototype, which of course you must always prevent. In this
case I think James ran into the following issue, which also has bitten
me a couple of times.
The problem arises if you have two classes, each declaring a method
with some identical name, but differing return types:
- (float) position;
- (int) position;
In this case, the compiler will use the method signature of whichever
one it encounters first in the compilation process, which is usually
the precompiled headers and hence, Cocoa methods which take priority.
In this case there is no warning of any kind (and there isn't one
currently available that I have been able to find) that warns of a
possible ambiguity, but the code generated is wrong. This is what
caused the recent memory corruption bug that afflicted DK when
compiling against the 10.5 SDK. Under 10.4, there was no ambiguity
because the method name involved happened only to exist in DK, but in
the 10.5 SDK, Apple had added two methods that happened to have a
conflicting name. And in fact, that name was 'position' so that method
name in particular is already known to be potentially problematic.
The problem can be disambiguated if the class involved is strongly
typed, but if typed generically as 'id' will cause problems.
The real problem is a lack of namespaces in Objective-C, but the
workaround is to avoid the 'id' type if you can. This is what bit me
though:
- (int) sortComparisonFunction( id a, id b, void* info )
{
float posA = [a position];
float posB = [b position];
// compare posA to posB...
}
This function prototype is the one Apple actually recommends for sort
comparison functions, taking type id. However the method signature
actually used by the compiler will be the first found for 'position',
which in Apple's classes returns an int or a compound structure, not a
float. The compiler, without warning, generates code that deals with
the int or compound struct result, which is completely bogus. By
strongly typing the params to the sort function as the real object
class, the compiler does the right thing.
There are probably a number of similar situations that result in the
same problem. It's also one that's very hard to predict until you are
made aware of it, since there is no warning of any kind, and at
runtime things might not show up as a bug very readily (for example in
my case the sort function was often working even though the values it
was sorting on were almost completely random, because it was a) called
rarely, b) usually with only two objects to sort and c) the random
values were often in the correct order by chance anyway). So there was
no obvious runtime bug that showed this piece of code was faulty - in
fact the symptoms of it was a hang in a completely unrelated place
caused by the memory corruption that this produced as a side effect.
Another way to prevent it is to prefix every single method in your own
classes with something unique that Apple won't ever use, but that's
really clunky and difficult to do long after the methods have already
been written. However, awareness of the issue is most of the battle.
cheers, Graham
On 23 Jun 2008, at 12:30 pm, Alex Curylo wrote:
>
> On 22-Jun-08, at 7:19 PM, Graham Cox wrote:
>
>> One thing to note in general is that if you ever have a method that
>> returns a float, it is essential that anything that needs to call
>> it imports its class's header so that it has the correct prototype.
>
> That applies to "any non-default result", not just "a float".
>
>> If not you get bizarre results that can even cause memory
>> corruption, not just bad return values, yet the compiler will give
>> absolutely no warning.
>
> Unless you have set
>
> GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
>
> like you should do if you would like to have any confidence that
> your code will, y'know, work.
>
> --
> Alex Curylo -- alex at alexcurylo.com -- http://www.alexcurylo.com/
>
> "It was the most surreal feeling. Like:
> What _IS_ this pickaxe doing stuck in my skull??"
> -- James "ragwing" Asher
>
>
>
> _______________________________________________
> Drawkit mailing list
> Drawkit at lists.apptree.net
> http://lists.apptree.net/listinfo.cgi/drawkit-apptree.net
More information about the Drawkit
mailing list