[英]Precision loss when passing arguments using va_list and printf
我有一個日志功能,其工作方式如下:
// 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");
}
(旁注:這應該與普通的printf完全相同,因此在這種狀態下它是無用的。這是因為這是一個極小的工作示例。最后,這應該與ncurses一起使用 - 請參閱注釋部分。)
然后我創建一個名為ui的ConsoleUI類的實例:
ConsoleUI ui;
后來我用它來記錄東西,更確切地說,是一個以微秒為單位的time_duration:
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());
我得到的輸出:
logged dt: 0.000000
logged dt 2: 140736013247624
dt: 0.018739
dt 2: 18739
我的期望:
logged dt: 0.018739
logged dt 2: 18739
dt: 0.018739
dt 2: 18739
請注意,通過多次調用,最后兩行中的值稍有變化(如預期的增量時間),前兩個值不會改變 - 這看起來格式有問題。
所以,底線:調用printf直接工作,但將其傳遞給記錄器,然后調用printf不起作用...
由於您實際上無法將參數從log
傳遞給printf
,因此您傳遞的是va_list
- 這是正確的解決方案,但您無法將va_list
傳遞給printf。
這一行:
printf( format.c_str(), args);
打印args
與格式format
。 假設args
的類型為va_list
(通常在編譯器ABI中作為void指針實現),它將不代表您在格式字符串中所期望的數據。 如果你使用
vprintf( format.c_str(), args);
它應該工作得很好,這就是vprintf
的用途。
(請注意,它與“精度損失”無關 - 它將不正確的參數類型傳遞給printf - 並且因為它是一個程序化的字符串,即使啟用警告也不會起作用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.