linux不知道的一些事兒

  1. 關於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>,則具有同樣的效果!

  1. gmtime_r()和localtime_r() 
    <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>
    gmtime()和localtime()返回struct tm類型的指針,指向一個由系統靜態分配的結構,而無需用戶從堆中new申請內存。但該結構可能會被接下來的任何日期和時間函數調用覆蓋,是非線程安全的。所以應該使用可重入版本(reentrant )。奇怪的是可重入版本的返回值和原來一樣,和第二個參數result重複了啊。只是返回值是一個指針,指向系統靜態分配的結構,而result一般是一個局部變量的地址,這是什麼設計。
    變態的是:POSIX.1-2004對localtime實現的要求是 tzset被默認調用,也就是說時區無需用戶關心。而對localtime_r則沒做要求,所以出於可移植考慮,應該先調用tzset。好在linux默認是實現的,不需關心這個問題!





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章