Warning: “format not a string literal and no forma

2019-01-03 05:23发布

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?

11条回答
疯言疯语
2楼-- · 2019-01-03 05:26

I've just been passing a nil to negate the warnings, maybe that would work for you?

NSLog(myString, nil);

查看更多
戒情不戒烟
3楼-- · 2019-01-03 05:29

If you want get rid of the warning "format not a string literal and no format arguments" once and for all, you can disable the GCC warning setting "Typecheck Calls to printf/scanf" (GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO) in your target's build settings.

查看更多
家丑人穷心不美
4楼-- · 2019-01-03 05:30

Just letting anyone know using the appendFormat on NSMutableString can also cause this warning to appear if trying to pass in a formatted string like so:

NSMutableString *csv = [NSMutableString stringWithString:@""];
NSString *csvAddition = [NSString stringWithFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];
[csv appendFormat:csvAddition];

So to avoid this warning, turn the above into this:

NSMutableString *csv = [NSMutableString stringWithString:@""];
[csv appendFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];

More concise and more secure. Enjoy!

查看更多
Rolldiameter
5楼-- · 2019-01-03 05:32

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]);
查看更多
何必那么认真
6楼-- · 2019-01-03 05:32

Quickest way to fix it would be to add @"%@", as the first argument to your NSLog call, i.e.,

NSLog(@"%@", [NSString stringWithFormat: ....]);

Though, you should probably consider Sixteen Otto's answer.

查看更多
做个烂人
7楼-- · 2019-01-03 05:33

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]);              
查看更多
登录 后发表回答