- 关于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默认是实现的,不需关心这个问题!