Рассмотрим эти два способа получить время эпохи из даты, отформатированной в виде строки:
#include <iostream>
int main() {
struct tm tm_init = {0};
strptime("2012-10-26 16:00", "%Y-%m-%dT %H:%M", &tm_init);
long epoch = mktime(&tm_init);
struct tm tm_rand;
strptime("2012-10-26 16:00", "%Y-%m-%dT %H:%M", &tm_rand);
epoch = mktime(&tm_rand);
return 0;
}
Источник: http://ideone.com/3xMUm8. По сути, разница в том, что tm_init инициализируется 0, а tm_rand — нет. Первый запускает g++ (предполагая -Wall и -W), чтобы сказать:
test.cpp:4:24: warning: missing initializer for member ‘tm::tm_hour’ [-Wmissing-field-initializers]
и аналогичные сообщения для других полей в структуре tm. Однако, если я пропущу инициализацию, как во втором случае, valgrind скажет мне:
==9892== Conditional jump or move depends on uninitialised value(s)
==9892== at 0x51E957C: __offtime (offtime.c:40)
==9892== by 0x51EBBE7: __tz_convert (tzset.c:653)
==9892== by 0x51E9EDB: __mktime_internal (mktime.c:310)
==9892== by 0x400786: main (test.cpp:10)
Конечно, последнее намного хуже первого, но я тоже не люблю предупреждения. Конечно, я могу инициализировать все поля вручную, написав какую-нибудь tm factory; но это потребовало бы от меня написания кода в зависимости от логики mt, и мне понадобилось бы два написания фабрики (блеф).
Это ошибка в ctime? К сожалению, мне не удалось найти (полу)официальную документацию по strptime, то есть страницы cplusplus.com по нему нет. Я что-то пропустил? Каков хороший способ проанализировать строку до эпохи?
ИЗМЕНИТЬ:
Как было предложено в некоторых ответах, я должен вручную установить для tm_isdst значение -1, 0 или 1. Однако это:
#include <iostream>
int main() {
struct tm tm;
strptime("2012-10-26 16:00", "%Y-%m-%dT %H:%M", &tm);
tm.tm_isdst = 0;
long epoch = mktime(&tm);
return 0;
}
Результаты в valgrind говорят следующее:
==11329== Conditional jump or move depends on uninitialised value(s)
==11329== at 0x51E9917: __offtime (offtime.c:83)
==11329== by 0x51EBBE7: __tz_convert (tzset.c:653)
==11329== by 0x51EA513: __mktime_internal (mktime.c:310)
==11329== by 0x40078D: main (test.cpp:7)
Итак, должен ли я также установить _offtime?
tm tm_rand
, хотя я думаю, что должны. Я проверю это с последними версиями gcc и clang и, если проблема все еще существует, отправлю отчет об ошибке. - person Ali   schedule 13.06.2014