On Jul 1, 2010, at 16:02, Paul Summermatter wrote:
Folks,
We're trying to upgrade and build our iPhone project with Xcode 3.2.3. Our project links with a static library/framework, and, as such, the source for this framework is rebuilt every time with our project. Under Xcode 3.2.2, this framework built without warnings or issues. Under 3.2.3, the code is failing to build with the following error:
warning: format not a string literal and no format arguments
Note that I said error, even though the output says warning. Xcode flags this in red and fails to build the project because of it. Here is the code which is generating this error:
NSString * const MyException = @"MyException";
static NSString * const ExceptionMessage = @"Bindings are not supported on the iPhone in Core Plot";
-(void)aMethod:(NSObject *)anObject
{
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
[NSException MyException format:ExceptionMessage];
So, I have a few questions: 1) the format is definitely a string literal, so why is the first part of this warning being generated (or is the grammar of the warning wrong/bad, and should it say "format not a string literal OR no format arguments")
This warning is because you may think that you can pass a message string directly to a format, so the ExceptionMessage may be a (dynamically generated) string for the message itself. When that message contains percent characters, those will be interpreted wrongly as a format specifier, and you will get a crash. That's why you get a warning. If you pass arguments, it's clear to the compiler that you're not in that situation, so it really should be "and" in the warning message.
And in your case the format is NOT a string literal, it's a const string, which is something different (the compiler sees an NSString*). You probably are better off using a real string literal, perhaps by using a macro, rather than a static const NSString *.
BTW, if you do want to pass a (generated) message to a format parameter, the way to do this is to use @"%@" as format and pass the message itself as a format argument. Though in this case that would not be necessary, however you should better not pass strings like this.
2) why is this an error that is causing the build to fail 3) why is the behavior of the build different from 3.2.2 to 3.2.3?
I am not sure, perhaps the compiler's warning system is a bit different, whether they also look at const strings or not, or some (default) warning flags are differently.
What I've found is that, if I change the code as follows:
-(void)aMethod:(NSObject *)anObject
{
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
[NSException MyException format:@"Bindings are not supported on the iPhone in Core Plot"];
There is no warning or error at all, even though the format still has no arguments.
But now you DO have a string literal.
I would at least expect to still get a warning that I have no arguments to format.
No, remember that the message has and "and", and when one of the conditions in a logical "and" _expression_ is false, than the whole _expression_ is false (i.e. there's no reason for a warning).
Further, if I create code in the main project (remembering that this code in question is in a static framework) that mirrors the original version of the code above, I get a build warning and not a build error. So, as part of the same build, the same errant code in one spot generates a true warning and in another spot generates an error.
That tells me that probably the build settings of the framework are different, perhaps something like "treat warnings as errors"?