Sunday, November 14, 2010

Why ignoring compiler warnings is bad

Imagine that you're observing the following bug: for some reason your method gets its arguments with values different from what it was called with. Then you learn that it's not a debugger's fault, because adding a couple of NSLog's gives the same result. Then you learn that it's not a compiler's bug too, because changing it to clang/llvm gives nothing too. WTF?!, you think now.

The make the situation more real, here's the code which can help to feel that:

// MyClass.h
@interface MyClass : NSObject {
}
- (void)printFloat2:(float)x;
@end
// MyClass.m
@implementation MyClass
- (void)printFloat:(float)x {
 NSLog(@"x = %f", x);
}
- (void)printFloat2:(float)x {
 NSLog(@"x = %f", x);
}
@end
// main.m

 

#import <Foundation/Foundation.h>
#import "MyClass.h"
int main(int argc, char *argv[]) {
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
MyClass * obj = [[MyClass alloc] init];
[obj printFloat:42.0];
[obj printFloat2:43.0];
[obj release];
[pool release];
return 0;
}

What you think will it print out? Well, here's the answer:

x = 0.000000
x = 43.000000

You see that the first line looks a bit wrong.

So, what's wrong? To tell the truth, I don't fully understand it and I would be glad if you could explain it. What is obviously not good it that we have a compiler warning at the appropriate line. -[MyClass printFloat:] isn't public so the compiler warns us that it can't find the method. Fixing that by declaring the method as public resolves the bug. Another good reason to fix all warnings in the code.

Here's what I discovered while trying to understand why does it behave so:

1. If we change argument type to double, everything works fine without declaring the method.

2. If we substitute obj with a proxy in order to dump NSInvocation, we see that methods have the same signature, but the argument is already different at the moment of forwardInvocation:.

It looks clear that the compiler somehow uses information from method declaration when storing the argument, but I don't understand why and how.

0 comments:

Post a Comment