Convert Log macro to objective C string
Convert Log macro to objective C string
We have a C++ library with the below DebugLog macro which writes to a file
std::string var("some string");
DebugLog( << "Output" << var );
We want to use this in our Objective C code so that both the ObjC and C++ library are writing to the same log file.
In our existing ObjC we use a log macro which when used with format parameters produces no warning from compiler
LOG("Error description %s", [[error localizedDescription] UTF8String]);
However all usages without format parameters produce warnings eg
LOG("initialising")
The LOG macro is defined as shown below and is generating a warning 'Format string is not a string literal'. Anyone know how to improve the code to remove this warning.
#define LOG(fmt, ...) do
NSString *tmp =[NSString stringWithFormat:[NSString stringWithUTF8String:fmt], ##__VA_ARGS__];
DebugLog( << [ tmp UTF8String] );
while(0)
NSLog
sorry we can't modify the library
– tech74
Sep 2 at 7:11
If you use your macros passing an NSString into it like this:
LOG(@"format", params)
then you probably don't need stringWithUTF8String
in the code.– algrid
Sep 2 at 7:39
LOG(@"format", params)
stringWithUTF8String
We have thousands of these LOG statements so wanted to resolve it this way rather than attempting to change like that if possible
– tech74
Sep 2 at 7:50
Haven't done C++ is donkeys years, but almost all functions that take a format string will emit a warning if your try to pass a variable for that format. The danger is that the variable string may contain characters that get interpreted ("progress is 50% complete") may cause odd behavior or crashes. The "solution" is to pass the variable as a variable, so something like
"%s",tmp.UTF8String
, in however you'd write that in the ugly-operator-overload-abused world of C++ these days.– James Bucanek
Sep 2 at 16:53
"%s",tmp.UTF8String
1 Answer
1
From your examples it appears you are using LOG
with a C-string as the format string, on that basis your original NSLog
version could be:
LOG
NSLog
#define LOG(fmt, ...) NSLog(@fmt, ##__VA_ARGS__);
provided fmt
is always a literal string. Macros operate before lexical analysis (or at least effectively do so, dependent on implementation) – hence the term "pre-processor" for the part of the compiler which handles macros, conditional compilation, etc. Given this your macro example:
fmt
LOG("Error description %s", [[error localizedDescription] UTF8String]);
expands to:
NSLog(@"Error description %s", [[error localizedDescription] UTF8String]);
and the compiler sees the format string as an Objective-C string.
In a similar way you can rewrite your macro to use your C++ function as:
#define LOG(fmt, ...) DebugLog( [NSString stringWithFormat:@fmt, ##__VA_ARGS__].UTF8String );
HTH
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What C++ library are you using? You may be able to just figure out the file and keep
NSLog
– Dair
Sep 2 at 0:12