ETH官方钱包

前往
大廳
主題

C語言的sizeof(long)和下一個千禧蟲問題

Yang | 2023-01-08 10:58:38 | 巴幣 0 | 人氣 549

目前測試,sizeof(long)在CentOS7(Linux)/AIX7(Unix)是8,在Win10(Windows)是4

參考文章

原因是不同平臺的C Language Data Model不同,Linux/Unix是LP64,Windows是LLP64

沒想到這是下一個千禧蟲問題!參考Wiki:

C語言的時間資料結構常見有timeval(舊版,< c11)或timespec(新版,>= c11)

struct timeval {
  long tv_sec; /*seconds since 1/1/1970*/
  long tv_usec; /*microseconds since tv_sec*/ //微秒
};

struct timespec {
  time_t tv_sec; /*seconds since 1/1/1970*/
  long tv_nsec; /*nanoseconds (valid values are [0, 999999999])*/ //奈秒
};

如果sizeof(long)或sizeof(time_t)是4,時間會在西元2038年用盡!

到時所有的32位元系統或程式取時間都會出現異常,連目前在64位元Windows上的C語言程式取時間也會異常

(不過微軟(MS)就是M$,相信在2038年以前,大家都會掏$給微軟,購買新版Windows,解決C Language Data Model問題)


從Linux/Unix傳遞時間給Windows,解析上要特別判斷,因為Linux/Unix上timeval或timespec是8+8=16個bytes,Windows上是4+4=8個bytes,反之亦然


自定義的資料結構,宜用long long取代long


int是4個bytes,最大值是2147483647,用來存放tv_usec(0~999999)或tv_nsec(0~999999999)都已經足夠

因為long tv_usec或long tv_nsec在Linux/Unix上,前4個bytes總是0,有特殊資料想隱藏時,可以利用前4個bytes儲存
送禮物贊助創作者 !
0
留言

創作回應

Shark
無意間看到這篇
由於C語言只規定char<=short<=int<=long<=long long,沒規定它們各是幾bytes,所以有不同編譯器byte數不同的情況。
如果需要固定大小的整數,可以#include<stdint.h>再用以下型態:
有號:int8_t、int16_t、int32_t、int64_t
無號:uint8_t、uint16_t、uint32_t、uint64_t

照微軟的官方文件,32位元環境下time_t也是64位元,除非你定義_USE_32BIT_TIME_T的macro。
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/time-time32-time64?view=msvc-140
我查過Visual C的time.h,是這樣沒錯。
Windows好像只有timespec而沒有timeval,我翻time.h時沒看到timeval。
反而Linux 32位元環境下time_t是32位元(在64作業系統執行32位元程式也是如此),time()以外沒有其他函式可以取得64位元時間,在2038年以前一定要把程式改寫成64位元。
2023-02-03 06:04:58
Yang
了解,感謝分享,我只有接觸gcc/g++,沒測試到Visual C
2023-02-03 22:50:34

更多創作