- 關於PRId64
Linux裏,int64_t(64位整數)經常被用來表示時間戳,因爲int32_t只能表示到格林威治時間2038年01月19日03時14分07秒,而64位整數表示的時間要長很多。但int64_t類型在32位系統中是long long int,在64位系統中是long int,這就帶來了問題,在打印int64_t的格式化方法時:
printf("%ld", value); // 64bit OS
printf("%lld", value); // 32bit OS
跨平臺的方法是:#include <inttypes.h>
printf("%" PRId64 "\n", value);
PRId64被定義爲32平臺上的"ld",64平臺上的"lld",而諸如printf("abc" "def" "ghi");這樣的語法是合理的。
注意,要想用該宏,需要事先定義__STDC_FORMAT_MACROS宏
/* The ISO C99 standard specifies that these macros must only be
defined if explicitly requested. */
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
# if __WORDSIZE == 64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
# endif
/* Macros for printing format specifiers. */
/* Decimal notation. */
# define PRId8 "d"
# define PRId16 "d"
# define PRId32 "d"
# define PRId64 __PRI64_PREFIX "d"
此外,如果在編譯時加入-std=c++0x新標準選項,頭文件#include <cinttypes>,則具有同樣的效果!
- gmtime_r()和localtime_r()
gmtime()和localtime()返回struct tm類型的指針,指向一個由系統靜態分配的結構,而無需用戶從堆中new申請內存。但該結構可能會被接下來的任何日期和時間函數調用覆蓋,是非線程安全的。所以應該使用可重入版本(reentrant )。奇怪的是可重入版本的返回值和原來一樣,和第二個參數result重複了啊。只是返回值是一個指針,指向系統靜態分配的結構,而result一般是一個局部變量的地址,這是什麼設計。<span style="font-size:14px;"> struct tm *gmtime(const time_t *timep); struct tm *gmtime_r(const time_t *timep, struct tm *result); struct tm *localtime(const time_t *timep); struct tm *localtime_r(const time_t *timep, struct tm *result);</span>
變態的是:POSIX.1-2004對localtime實現的要求是 tzset被默認調用,也就是說時區無需用戶關心。而對localtime_r則沒做要求,所以出於可移植考慮,應該先調用tzset。好在linux默認是實現的,不需關心這個問題!