문제

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...

도움이 되었습니까?

해결책

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).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top