Re: "Format not a string literal and no format arguments"
Re: "Format not a string literal and no format arguments"
- Subject: Re: "Format not a string literal and no format arguments"
- From: Ken Thomases <email@hidden>
- Date: Sat, 29 Aug 2009 14:25:25 -0500
On Aug 29, 2009, at 1:54 PM, Peter Duniho wrote:
Am I reading the right documentation? On this page:
http://developer.apple.com/mac/library/releasenotes/Cocoa/Foundation.html
I see this text:
Foundation APIs which take string format arguments (APIs
such as initWithFormat:, NSLog(), etc) are now decorated
with attributes which allow the compiler to generate
warnings on potentially unsafe usages. This currently
includes usage such as:
NSString *str = ...;
NSString *formattedStr = [[NSString alloc] initWithFormat:str];
where the format is not a constant and there are no arguments.
In a case like above, the call to initWithFormat: is
unnecessary, so to avoid warnings, just drop the call. In
a case like NSLog(str), you can instead use NSLog(@"%@", str).
I read that to mean that one will get the warning for _any_ call to
initWithFormat:, even those automatically generated by NSLog() (thus
the suggestion in the text for a work-around so as to prevent the
warning).
(Aside: The wording of the warning also seems weird to me, assuming
Jonathan quoted it verbatim. Why should a non-literal string format
be any more or less likely to include formatting specifiers that
would require format arguments? Or is it implied that the compiler
is doing compile-time verification of the format string when a
literal is provided?)
Not having Snow Leopard, nor Xcode 3.2, I can't test this myself and
I suppose I might be misunderstanding the question or the answer.
But it looks to me as though any usage of initWithFormat: that
doesn't pass format arguments will generate the warning, even
NSLog(@"Hello").
Is there some more specific documentation of the warning available
somewhere? I tried searching the docs for the warning text provided
in the previous post, but didn't find anything. Searching the web
using Google suggests that this is a gcc feature, intended for use
where actual string literals (e.g. "Hello", not @"Hello") would
appear (e.g. printf()), but based on the comments I saw in that
context, it's not clear to me why this warning would be all that
useful in the context of Cocoa anyway (since most "literals" are
really NSString objects, not checkable by the compiler).
Objective-C @"..." strings are still literals and constants, despite
also being objects.
You misunderstand when you "read that to mean that one will get the
warning for _any_ call to initWithFormat:". It happens when you pass
a non-constant format string and no arguments.
The problem case they are trying to avoid is something like this:
NSString* str = [self getAnArbitraryStringFromTheUserOrAnUnknownSource];
NSLog(str);
What if str ends up containing percent signs? Then the string-
formatting machinery behind NSLog will attempt to treat them as
formatting specifiers. It will likely try to access arguments to be
formatted, arguments which aren't there, resulting in undefined
behavior, possibly including crashing your app or corrupting your
data. This sort of thing is a pernicious bug which can also be taken
advantage of by malicious hackers.
So, using -initWithFormat: (or any other properly decorated string-
formatting method or function) with a constant format string allows
the compiler to check the format string and verify the argument list
to be sure it meets the requirements of the format strings. (So, yes,
it is "implied that the compiler is doing compile-time verification of
the format string when a literal is provided".)
When you don't provide a constant format string but you do provide
arguments, it is assumed that you at least haven't made the most
common form of mistake. Your code seems to recognize that the first
argument is a format string which may require further arguments. In
this case, the compiler can't check consistency between the format
string and the subsequent arguments, but generating a warning would
flag too much correct code.
Lastly, yes, this is the same GCC feature as used in C. It has been
extended to understand Objective-C -- it recognizes Objective-C string
literals and also the %@ format specifier.
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden