views:

108

answers:

1

Hi all,

recently i came across this function (used in a logger class). I understand what it does, but i do not know how:

void Reporter::print( const char* szFormat, ...)
{
    // note: m_out is a FILE*
    va_list args;
    va_start(args, szFormat);
    vfprintf( m_out, szFormat, args);
    va_end(args);
}

I read the reference, but still it's unclear to me. What is bugging me the most is that this doesn't work as expected. I get 0 for the last number and (null) for the string, although it should print some number greater than 0 and a path to a file.

Case 1:

rep.print( "Values: %08X %08X %08X %08X %08X %08X %d %s\n", val1, val2, val3, val4, val5, val6, source.GetLength(), szPath );
// source.GetLength() returns a size_t, szPath is a const char* and IS indeed a valid string

But changing it to this works fine:

Case 2:

rep.print( "Values: %08X %08X %08X %08X %08X %08X", val1, val2, val3, val4, val5, val6 );
rep.print( " %d %s\n", source.GetLength(), szPath );

Note that i'm compiling under MSVC++ 2008. The same code works fine (even the first case) under gcc. Is there a bug in the implementation of Reporter::print() or in the way I use the function? How can I make sure that it will work fine even when called as in the first case? And why does it even fail?

+3  A: 

The code for Reporter::print is fine. All it is doing is correctly initialising args to refer to the variable argument list, then passing that variable argument list on to vfprintf(), which knows what to do with it.

Your problem is likely that the %d format specifier (which requires an int type argument) does not match the type of the value returned by source.GetLength() (which I would hazard a guess is possibly a size_t). If you know the length will always fit into an int, then you can solve it with a cast conversion:

..., (int)source.GetLength(), ...

(this is so because the expected type of the arguments that are part of the variable argument list are not known to the compiler, unlike a normal prototype function declaration).

caf
It is a size_t (mentioned in my question). Unfortunatelly, this didn't help. I'm actually experiencing crashes (access violation in MS runtime library (msvcr90d.dll)). Everything works fine when `case 2` code is used. Really strange. (and i'm runing it on a LOT of files, so i hope this is not just plain luck that it works).
PeterK
Ok sorry, i was wrong (messed up the format string while debugging ... fast edits, oh boy). This was really the case - `size_t` somehow messed with the function or whatever. Casting to `int` resolved the issue. Thanks!
PeterK