Some tips in C
libstdc
-
opendir()打开目录后,目录内容发生改变,readdir()则不能正确获得目录内容。虽 然概率很低,还是会发生地 -
rename()不能跨mount point重命名文件,会返回EBUSY。移动、复制文件很复杂,可 以参考coreutils中src/copy.c的实现。
Playing with macro
-
多条语句的宏用
do { ... } while(0)括住 -
Round up to power of 2: (
uint32_tonly)#define round_up_to_next_power_of_2(v) do { \ v--; \ v |= v >> 1; \ v |= v >> 2; \ v |= v >> 4; \ v |= v >> 8; \ v |= v >> 16; \ v++; \ } while (0)
夏令时
夏令时会导致很多异常诡异的时间问题。
/* tz-dst.c */
#include <time.h>
#include <stdio.h>
int main( void ) {
time_t t;
struct tm temp_tm;
struct tm tm_out;
char tmp_time[32];
strptime("2012-10-04 11:12:13", "%Y-%m-%d %H:%M:%S", &temp_tm);
t = mktime(&temp_tm);
localtime_r(&t, &tm_out);
strftime(tmp_time, 27, "%Y-%m-%d %H:%M:%S", &tm_out);
printf("%d - %s\n", t, tmp_time);
return 0;
}
编译执行,再夏令时时区会有问题:
$ gcc tz-dst.c -o dst-test $ TZ=CST6CET ./dst-test # CST +6 with daylight saving time 1349370733 - 2012-10-04 12:12:13 $ TZ=CST6 ./dst-test # CST +6 without daylight saving time 1349370733 - 2012-10-04 11:12:13
秒数相同,但是转换后时间相差一小时。struct tm结构中tm_isdst可以用于判断当前
是否处于夏时令。localtime(), localtime_r(), mktime()不会参考这个值,而是从
环境变量TZ中获取是否考虑夏令时。
强制mktime()返回UTC时间的方法:
time_t mktime_utc(struct tm * timeinfo) {
char * tz_old = getenv("TZ");
time_t ret = 0;
putenv("TZ=UTC");
_tzset();
ret = mktime(timeinfo);
if (!tz_old) {
setenv("TZ=");
} else {
char buf[64];
sprintf(buf, "TZ=%s", tz_old);
setenv(buf);
}
_tzset();
return ret;
}