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)





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


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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)