views:

54

answers:

3

This is for practise. I try to build something similar to NSLog. Currently I have this:

#define LogThis(info) \
    [[MyLogger sharedLogger] logThis:info];\


- (void)logThis:(NSString*)info {
    fprintf(stderr, [[NSString stringWithFormat:@"  %@\n", info] cString]);
}

Currently all I can do is pass a simple @"string" to it, but no formats and arguments like I could with NSLog. The main advantage here is that I get rid of all this overhead which NSLog produces. For learning purpose I'd like to know how I can get multiple arguments to make something similar to NSLog, so that I could call:

LogThis(@"method foo received input value %d", inputValue)

Is this possible?

A: 

Look at this answer to a similar question.

Vladimir
A: 

There is a way, you define the last argument with a trailing '...'. To access the last arguments defined, prepend the argument name with ##. I have a similar Log macro that looks like:

#define LOGGER(format, args...)                                   \
    LogManager::log()->addEntry(format, ##args)

where the addEntry function takes in a printf-like format. An example call looks like

LOGGER("This is a debug string with %d arguments %s", 2, "hooray");
Matt
+3  A: 

Here’s how you define variadic macros in gcc’s cpp:

#define LogThis(format, ...) \
    do { printf(format, ## __VA_ARGS__); } while(0)
Nikolai Ruhe
wouldnt this just print out all my arguments separately?
Another Registered User
No. It does exactly what a plain printf would do. Because it is. The `do` `while` is only to make it behave it like a function if more statements would be added. See http://en.wikipedia.org/wiki/C_preprocessor#Multiple_statements
Nikolai Ruhe