Alec
Alec

Reputation: 1706

Misunderstanding of macros in iOS

There is something that I fundamentally don't understand because I cannot for the life of me get this to work. I want to create a macro that extends NSLog(NSString *format, ...). Here is what I came up with:

NSLogExtensions.h

#define DebugLog(debugMode, format, ...) MyDebugLog(debugMode, [[NSString stringWithFormat:@"<%@> (Line %d): ", NSStringFromClass([self class]), __LINE__] stringByAppendingString:format], ##__VA_ARGS__)

@interface NSLogExtensions : NSObject

@end

NSLogExtensions.m

#import "NSLogExtensions.h"

@implementation NSLogExtensions

void MyDebugLog(bool debugMode, NSString *format, ...) {
    va_list(argumentList);
    va_start(argumentList, format);
    if (debugMode) {
        NSLogv(format, argumentList);
    }
    va_end(argumentList);
}

@end

I expected to be able to include the NSLogExtensions header file and then be able to use the macro, but I receive the GCC implicit function declaration warning still.

Upvotes: 0

Views: 443

Answers (2)

Martin R
Martin R

Reputation: 540075

The DebugLog macro uses the function MyDebugLog, therefore you must add the prototype

void MyDebugLog(bool debugMode, NSString *format, ...);

to NSLogExtensions.h. Then it compiles without warnings.

BUT your solution has one (in my opinion) great disadvantage compared to the solutions that @calvinBhai refers to: Even if you switch off logging by setting debugMode to false, the DebugLog macro will evaluate all arguments and call MyDebugLog. With the other solutions, the preprocessor will remove everything if logging is disabled.

Upvotes: 1

Nitin Alabur
Nitin Alabur

Reputation: 5812

Checkout this answer

Is it true that one should not use NSLog() on production code?

it has a lot more detail on how to go about using a macro for your extended NSLogs

Upvotes: 2

Related Questions