портативный способ работы с 64/32 бит time_t - PullRequest
16 голосов
/ 18 марта 2010

У меня есть код, который построен как на Windows, так и на Linux. Linux на данный момент всегда 32-битный, а Windows 32-битный и 64-битный. Windows хочет, чтобы time_t было 64-битным, а Linux по-прежнему 32-битным. Я в порядке с этим, за исключением того, что в некоторых местах значения time_t конвертируются в строки. Поэтому, когда time_T 32-битный, это должно быть сделано с% d, а когда он 64-битный с% lld ... какой умный способ сделать это? Также: есть идеи, как найти все места, где time_t передаются функциям в стиле printf для решения этой проблемы?

редактирование: Я придумал объявить TT_FMT как «% d» или «% lld», а затем изменил мои printfs как в printf («время:% d, регистр: бла») будет printf («время:« TT_FMT », регистр: бла») Есть ли способ лучше? И как мне их всех найти?

Ответы [ 3 ]

11 голосов
/ 18 марта 2010

В соответствии со стандартом C, time_t является арифметическим типом, «способным представлять время». Так, например, это может быть double. (Posix упоминает это более явно , а также гарантирует, что time() возвращает количество секунд, прошедшее с начала эпохи - последнее не гарантируется стандартом C.)

Возможно, самое чистое решение - преобразовать значение в любой тип, который вы хотите. Вы можете хотеть один из unsigned long long или unsigned long:

printf("%llu\n", (unsigned long long)t);
7 голосов
/ 18 марта 2010

Я думаю, что единственный действительно переносимый способ - использовать strftime для преобразования time_t в строку.

Если вы уверены, что работаете только на платформах, где time_t является int, вы можете привести к intmax_t (из stdint.h) и распечатать его с помощью PRIdMAX (из inttypes.h).

3 голосов
/ 18 марта 2010

Если вы хотите использовать спецификатор макроса, я бы порекомендовал одну небольшую настройку. Вместо того, чтобы инкапсулировать весь спецификатор, инкапсулируйте только модификатор:

#ifdef 64_BIT_TIME
  #define TT_MOD "ll"
#else
  #define TT_MOD ""
#endif

, а затем использовать его так:

printf("current time in seconds is: %" TT_MOD "u", time(0));

Причина в том, что, хотя вы в первую очередь хотите, чтобы секунда в десятичной системе счисления, время от времени вам может понадобиться гекс (или, возможно, вы хотите получить 0). Имея только модификатор, вы можете легко написать:

"%" TT_MOD "x"   // in hex
"%08" TT_MOD "d"  // left pad with 0's so the number is at least 8 digits
...