Update: Thanks to a comment by Ted Kremenek I discovered that the official clang tool does not emit the warning discussed below. It turns out that the AnalysisTool.app frontend application that I've used ships with its own modified clang.
Reading his comment I've also realized that my post might be interpreted as a criticism on clang and this is not the case - I think clang is a great addition to the existing tools on Mac OS X. It's just that, unlike leaks, static checkers should be used before the testing stage.
clang and the static analyzer that's built on top of it work by analyzing your sources while being compiled and making suggestions. Sort of like the warnings in GCC but on a deeper level, e.g.:
'autorelease' should be called right after alloc & init. Do not leave the responsibility of calling 'release' until later stages.
But clang goes wrong as the code that follows the lines above is:
Trusting clang's warning without realizing that two lines later the string variable was already being auto-released results in a crasher due to over-releasing.
Sure, clang is right and it doesn't really make sense to not auto-release the string immediately on but from a functional point of view not acting on clang's warning produces leak-free workable code, while following it blindly (i.e. without re-reading the entire context) makes clang happy but yields a crasher.
Which is exactly what happened with releases 1.5 and 1.6 of BucharestApp.
The moral of the story? never ship untested code.
Reading his comment I've also realized that my post might be interpreted as a criticism on clang and this is not the case - I think clang is a great addition to the existing tools on Mac OS X. It's just that, unlike leaks, static checkers should be used before the testing stage.
clang and the static analyzer that's built on top of it work by analyzing your sources while being compiled and making suggestions. Sort of like the warnings in GCC but on a deeper level, e.g.:
NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
'autorelease' should be called right after alloc & init. Do not leave the responsibility of calling 'release' until later stages.
But clang goes wrong as the code that follows the lines above is:
if(string != nil)
[textBuffer appendString:string];
[string autorelease];
Trusting clang's warning without realizing that two lines later the string variable was already being auto-released results in a crasher due to over-releasing.
Sure, clang is right and it doesn't really make sense to not auto-release the string immediately on but from a functional point of view not acting on clang's warning produces leak-free workable code, while following it blindly (i.e. without re-reading the entire context) makes clang happy but yields a crasher.
Which is exactly what happened with releases 1.5 and 1.6 of BucharestApp.
The moral of the story? never ship untested code.