更多课程 选择中心

C/C++培训
达内IT学院

400-996-5531

C++中的2038问题到底是个什么问题?

  • 发布:守望
  • 来源:编程珠玑
  • 时间:2020-06-11 15:43

C++中什么是2038问题,不知道你有没有听过2038问题?无论你是否听过,本文将带你认识什么是2038问题。

Unix时间戳

定义为从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

而在C语言中,常用time_t来表示。举个例子:

#include <stdio.h>

#include <time.h>

int main (void)

{

time_t rawtime = 10;//time(NULL)获取当前时间戳

struct tm info;//转为tm结构

localtime_r( &rawtime,&info); //转为字符串

printf("时间为: %s\n", asctime(&info));

return 0;

}

运行结果:

时间为: Thu Jan 1 08:00:10 1970

在这里,我给rawtime设置为10,从打印结果来看也知道是正确的了。(注意,由于我们的时区为东八区,所以得到的时间是八点。)当然这里的内容暂时不展开,主要关注time_t。然而实际上,time_t到底是什么?

通常,time_t直接或者间接被定义为下面这样:

typedef long time_t

我们知道,在32位程序下面,long占用四个字节空间:

#include<stdio.h>

#include <limits.h>

int main(void)

{

printf("long size:%zd\n",sizeof(long));

printf("long max:%ld\n",LONG_MAX);

return 0;

}

编译运行:

$ gcc -m32 -o main main.c

$ ./main

4

2147483647

可以看到,对于32位程序而言,long的最大值为2147483647。

溢出引发的问题

也就是说,一旦时间戳的值大于四字节的LONG_MAX,time_t将会无法正确存储这个时间戳。

举例来说,最开始的程序编译为32位程序,修改rawtime的值为2147483648,运行结果为(注意,溢出的结果是未定义的):

#include <stdio.h>

#include <time.h>

int main (void)

{

time_t rawtime = 2147483648;//time(NULL)获取当前时间戳

struct tm info; //转为tm结构

localtime_r( &rawtime,&info); //转为字符串

printf("时间为: %s", asctime(&info));

return(0);

}

然后我们编译运行:

$ gcc -m32 -o main main.c

warning: this decimal constant is unsigned only in ISO C90 [enabled by default]

$ ./main

间为: Sat Dec 14 04:45:52 1901

首先编译的时候也有警告,原因在于2147483649无法使用time_t来表示,我们运行之后,也发现结果出乎我们的意料,它竟然是一个1901年的时间!

2038问题

那这和2038有什么关系呢?

编译为64位程序我们再次运行就会发现:

间为: Tue Jan 19 11:14:08 2038

这个4字节整型表示的时间戳值只能表示到北京时间2038年1月19日11时14分07秒,一旦到了这时间之后,这些32位程序就可能运行异常,因为它们无法将此时间正确的识别为2038年,而可能会依个别实现而跳回1970年或1901年。

总结

到此,想必你已经很清楚了。由于在32位程序中,time_t最大值为2147483647,即最多表示到北京时间2038年1月19日11时14分07秒,因此在此之后就会出现异常。而如果使用64位整型,则可以记录至约2900亿年后的292,277,026,596年12月4日15:30:08,星期日(UTC)。

当然,如果采用无符号整型,这个错误会被延后到 2106 年。到那时,还会有32位的程序在运行吗?

2038问题只是一个引子,实际上在程序中有很多现在不会溢出而将来可能溢出的问题,你会关注吗?

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:嵌入式学习路线图怎么学?
下一篇:C++中是如何调用C接口的?

空指针到底是什么意思?

a[i] = i++ 到底对不对?

C++培训哪家好?全方位对比机构

C/C++中的必须熟记的基础知识

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省