在RTL8710上,localtime()关闭了大约460,000年

Siz*_*e43 1 c embedded localtime

我正在使用RTL8710(运行rustl8710,但就这个问题而言,这是无关紧要的,因为我所说的所有代码都是C代码).RTL8710具有系统某些部分的专有库,包括localtime.

但是,localtime当使用它时,似乎已经过了大约460,000年(取自包含的NTP实现):

long current_sec = 1543067026;
struct tm current_tm = *(localtime(&current_sec));
Run Code Online (Sandbox Code Playgroud)

这将返回以下结构:

{tm_sec = 51, 
 tm_min = 36, 
 tm_hour = 15, 
 tm_mday = 25, 
 tm_mon = 8, 
 tm_year = -458682, 
 tm_wday = 2, 
 tm_yday = 267, 
 tm_isdst = -1515870811}
Run Code Online (Sandbox Code Playgroud)

显然这是不正确的,应该是接近2018年11月24日格林尼治标准时间13:52:04.但这并不是随机的,因为时间似乎总是相差大约2小时和几分钟.

这里唯一的其他值得注意的一点是,代码使用默认的系统头time.hstring.h(这将是从Ubuntu的18.10,在我的情况下,64位).

我不知道RealTek正在使用什么stdlib库,但是通过调试info(newlib/libc/time/lcltime.c)来判断,我猜它是newlib的(修改后的?)版本.

chu*_*ica 5

代码使用了错误的类型,导致未定义的行为.1

// long current_sec = 1543067026;
time_t current_sec = 1543067026;
struct tm current_tm = *(localtime(&current_sec));
Run Code Online (Sandbox Code Playgroud)

更好的代码将localtime()在取消引用之前测试返回值.

struct tm *p = localtime(&current_sec);
if (p) {
  struct tm current_tm = *p;
  ...
Run Code Online (Sandbox Code Playgroud)

1 错误的类型宽度可通过以下方式证明.

int main() {
  long current_sec = 1543067026;
  struct tm current_tm = { .tm_sec = 51, .tm_min = 36, .tm_hour = 15, //
      .tm_mday = 25, .tm_mon = 8, .tm_year = -458682, //
      .tm_wday = 2, .tm_yday = 267, .tm_isdst = -1515870811 };

  time_t t = mktime(&current_tm);
  printf("%16lx\n%16llx\n", current_sec, (unsigned long long) t);
}
Run Code Online (Sandbox Code Playgroud)

产量

        5bf95592
fffff2d55bf9a9f3
        ^^^^
Run Code Online (Sandbox Code Playgroud)

很多位排队.我怀疑高位差是由于垃圾位被引用local_time()而由于极端计算导致的低位差异,OP非同步发布代码和声称的输出,或者我和OP的标准库之间存在差异.虽然time_t是无区域,但我和OP的时区差异导致了locatime()/mktime()差异.