Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning: "format not a string literal and no format arguments"

Since upgrading to the latest Xcode 3.2.1 and Snow Leopard, I've been getting the warning

"format not a string literal and no format arguments"

from the following code:

NSError *error = nil;  if (![self.managedObjectContext save:&error])  {     NSLog([NSString stringWithFormat:@"%@ %@, %@",         errorMsgFormat,         error,         [error userInfo]]);        } 

If errorMsgFormat is an NSString with format specifiers (eg: "print me like this: %@"), what is wrong with the above NSLog call? And what is the recommended way to fix it so that the warning isn't generated?

like image 308
Alexi Groove Avatar asked Nov 05 '09 01:11

Alexi Groove


People also ask

Which of the following is not a string literal?

freshair is not a valid string literal. Hence, option(c) is correct option. String are data types is used to store sequence of characters, variables, numbers, or symbols. The string can be declared in double quotes or single quotes.

Which is the string literal?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string. You must always prefix wide-string literals with the letter L.


2 Answers

Xcode is complaining because this is a security problem.

Here's code similar to yours:

NSString *nameFormat = @"%@ %@"; NSString *firstName = @"Jon"; NSString *lastName = @"Hess %@"; NSString *name = [NSString stringWithFormat:nameFormat, firstName, lastName]; NSLog(name); 

That last NSLog statement is going to be executing the equivalent of this:

NSLog(@"Jon Hess %@"); 

That's going to cause NSLog to look for one more string argument, but there isn't one. Because of the way the C language works, it's going to pick up some random garbage pointer from the stack and try to treat it like an NSString. This will most likely crash your program. Now your strings probably don't have %@'s in them, but some day they might. You should always use a format string with data you explicitly control as the first argument to functions that take format strings (printf, scanf, NSLog, -[NSString stringWithFormat:], ...).

As Otto points out, you should probably just do something like:

NSLog(errorMsgFormat, error, [error userInfo]); 
like image 188
Jon Hess Avatar answered Oct 15 '22 14:10

Jon Hess


Are you nesting your brackets correctly? I don't think NSLog() likes taking only one argument, which is what you're passing it. Also, it already does the formatting for you. Why not just do this?

NSLog(@"%@ %@, %@",     errorMsgFormat,     error,     [error userInfo]);               

Or, since you say errorMsgFormat is a format string with a single placeholder, are you trying to do this?

NSLog(@"%@, %@", [NSString stringWithFormat:errorMsgFormat, error],     [error userInfo]);               
like image 35
Sixten Otto Avatar answered Oct 15 '22 13:10

Sixten Otto