Question

I have a logging function which works like this:

// public function:
void ConsoleUI::log(const std::string& format, ...) {
    va_list args;
    va_start(args, format);
    log(format, args);
    va_end(args);
}

// overloaded private function:
void ConsoleUI::log(const std::string& format, va_list args) {
    //wprintw( outWin, format.c_str(), args);
    //wprintw( outWin, "\n");
    printf( format.c_str(), args);
    printf( "\n");
}

(Side note: This should do the exact same thing as just a normal printf, so it's pretty useless in this state. That's because this is a minumal working example. In the end, this should work with ncurses - see commented section.)

I then create an instance of the ConsoleUI class, called ui:

ConsoleUI ui;

And later I use it to log stuff, more precisely, a time_duration in microseconds:

now = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration delta = now - lastTime;
double dt = 1e-6*(double)delta.total_microseconds();
lastTime = now;

ui.log( "logged dt: %f", dt );
ui.log( "logged dt 2: %lu", delta.total_microseconds());
printf( "dt: %f\n", dt);
printf( "dt 2: %lu\n", delta.total_microseconds());

The output I get:

logged dt: 0.000000
logged dt 2: 140736013247624
dt: 0.018739
dt 2: 18739

What I expected:

logged dt: 0.018739
logged dt 2: 18739
dt: 0.018739
dt 2: 18739

Note that over multiple calls of this, the values in the last two lines change slightly (as is to be expected of a delta time) and the first two values don't change - which looks like there's something wrong with the format.

So, bottom line: Calling printf directly works, but passing it down the logger and then calling printf doesn't work...

Était-ce utile?

La solution

Since you can't actually pass your arguments from log to printf, you are passing a va_list - this is the right solution, but you can't pass a va_list to printf.

This line:

    printf( format.c_str(), args);

prints args with the format in format. Given that args is of the type va_list (typically implemented in the comiler ABI as a void pointer) it will not represent the data that you expect in the format string. If you use

   vprintf( format.c_str(), args);

it should work just fine, that's what vprintf is for.

(Note that it's nothing to do with "loss of precision" - it's passing incorrect type of argument to printf - and since it's a programmaticly formulated string, even enabling warnings is not going to work).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top