0

I am tying to generalize calling NSLog and avoid having to comment-out the calls when I am finished debugging.

I have:

#define USE_ADLog 0
#define USE_RPLog 0
#define USE_DLLog 1

void ConsoleADLog(NSString *message, ...);
void ConsoleRPLog(NSString *message, ...);
void ConsoleDLLog(NSString *message, ...);

and, for example:

void ConsoleADLog(NSString *message, ...) {

#if (USE_ADLog)
    va_list optionalArgs;

    va_start(optionalArgs, message);   // after the parm = message
    va_end(optionalArgs);

    NSLog(message, optionalArgs);
#endif
}

So far, so good ... however, as soon as I call, for example,:

   ConsoleDLLog(@"parm1 = %@, parm2 = %@", parm1, parm2);

which call is inside a secondary thread, I bomb. I thought?? that va_start, va_end were thread safe.

... or is the problem %@ ... I know %f works ???

Apparently not!, so how do I make them thread safe ... plain ole

NSLog(@"whatever %@", whateverParm)

works, but not the function above.

Thanks,

9dan
  • 4,222
  • 2
  • 29
  • 44
  • Check this topic: http://stackoverflow.com/questions/969130/nslog-tips-and-tricks – Michał Zygar Aug 25 '11 at 09:26
  • Several things I don't understand. Why are you releasing optionalArgs in va_end before using it? shouldn't you save it with something like `msg = [[[NSString alloc] initWithFormat:message arguments:optionalArgs] autorelease]; va_end(optionalArgs);` then NSLog the msg? Do you really want NSLog for the ASL? you could use fprintf instead. – Jano Aug 25 '11 at 10:57

2 Answers2

1

this is why many variadic functions include variants which accept va_lists.

see NSLogv.

justin
  • 104,054
  • 14
  • 179
  • 226
  • Amen ... used NSLogv(@"whatever %@, whateverParm) and all became good ... BUT, since NSLog just calls NSLogv, why doesn't using NSLog here work. I know that "Ours is not to reason why, etc. etc." ... but WHY? –  Aug 25 '11 at 10:11
  • see QA in accepted answer here: http://stackoverflow.com/questions/3143906/how-to-use-va-args-to-pass-arguments-on-variadic-parameters-elipsis – justin Aug 25 '11 at 10:16
  • Thanks, Justin ... The WHY? comes from Yuji "You can't. Once ... is converted to va_list, it can be only passed to a function or a method which accepts va_list, not to a function/method which accepts a variable number of parameters." –  Aug 25 '11 at 10:20
  • vas are opaque and implementation defined. furthermore, va initialization operates uses local addresses - there is no explicit storage to specify (pass by argument to the function) a user defined address (e.g. the address of the external function's first argument in the valist). if you wanted to forward this info, you could do so by adding an argument to all your variadic functions, but that is more complex than adding va_list variants (imo). – justin Aug 25 '11 at 15:02
0
#if DEBUG == 0
#define DebugLog(...)
#elif DEBUG == 1
#define DebugLog(...) NSLog(__VA_ARGS__)
#endif

Then invoke it using DebugLog(@"Uh oh: %@", someArgument);. If DEBUG is set to 1, the preprocessor will emit NSLog(@"Uh oh: %@", someArgument);. If it's set to 0, it will not emit anything.

Isaac Overacker
  • 1,385
  • 10
  • 22
  • Forgive me because I just don't remember the specifics ... but, with Xcode 4 (not with 3) the line #define DebugLog(...) with an empty equivalent produced some sort of (extraterrestial) warning about something. Darn, I wish I could remember! –  Aug 25 '11 at 10:23