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_t
only)#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; }