fprintf и difftime безумие - PullRequest
       5

fprintf и difftime безумие

0 голосов
/ 10 декабря 2011

Искал ответ для этого, но не мог ничего найти. Самое близкое, что я мог найти, было difftime возвращает 0, когда есть явная разница Что имеет большое объяснение, касающееся того, как аргументы помещаются в стек и что ожидает формат, но я думаю, что моя проблема в другом:

Я сделал как можно более простой пример. Предположим, у меня есть следующий код в C:

time_t starttime = time(NULL)
somefunction();
time_t newtime = time(NULL)

fprintf(stderr, "starttime %f and difftime %f\n", starttime, difftime(newtime, starttime));
fprintf(stderr, "difftime %f and starttime %f\n", difftime(newtime, starttime), starttime);
return 0;

И некоторые функции - это некоторые функции, которые выполняются в течение 1 или 2 секунд. Вывод, который я получаю для этого:

starttime 2.000000 and difftime 0.000000
difftime 2.000000 and starttime 0.000000

Я даже не знаю, с чего начать мой вопрос. Почему, когда я меняю порядок, выводимые значения остаются прежними? Кроме того, почему одно из значений 0? Это то же самое, использую ли я% f,% d,% lu,% llu и т. Д. Есть ли объяснение стек-аргумента этому? Что на самом деле делает fprintf внутри?

Спасибо. Я потратил слишком много своей жизни, пытаясь отладить это, и я был бы очень признателен за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 10 декабря 2011

Спецификатор "%f" не подходит для time_t на вашей платформе.Насколько я знаю, тип time_t может быть целым или вещественным.

Например, стандарт POSIX просто говорит:

time_t и clock_t должно быть целочисленным или вещественным типом.

Попробуйте это:

/* Flawed bad and wrong. */
printf("%f\n", (double)starttime);

Я видел предложения привести его к uintmax_t, unsigned long long и т. Д. Очевидно,реальный ответ - здесь :

Не существует единого способа printf () time_t, period.Вы не должны этого делать - вам даже не нужно знать, что такое time_t внутри.Предлагаемые альтернативы включают ctime () и strftime ().Пожалуйста, используйте их, чтобы сохранить код переносимым.

1 голос
/ 10 декабря 2011

starttime - это time_t, но вы должны напечатать его с %f, что предполагает double.Очевидно, на вашей платформе time_t является неким целочисленным типом.

Вероятно, соглашение о вызовах вашей платформы для функций списка переменных-аргументов, таких как fprintf(), передает аргументы с плавающей точкой в ​​другом месте, чем целочисленные аргументы.

Функция difftime(), вероятно, возвращает 2.0, что передается в первом местоположении аргумента с плавающей точкой, поэтому первый %f печатает 2.0 в обоих случаях.Второй аргумент с плавающей точкой содержит ноль, поэтому второй %f печатает ноль в обоих случаях.Аргумент time_t помещается в другое место, которое вообще не проверяется кодом fprintf().

...