tech74
tech74

Reputation: 1659

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) \

Upvotes: 2

Views: 244

Answers (1)

CRD
CRD

Reputation: 53000

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:

#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:

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

Upvotes: 1

Related Questions