Windowsでは、次のように呼び出すことができます。
_time32(__time32_t); // to get 32-bit time_t
_time64(__time64_t); // to get 64-bit time_t
(32ビットプログラムと64ビットプログラムの両方)
Linux(GCCでコンパイル)でこれを行う方法はありますか?
どうやら、それは不可能です。time()
まず、Linux には notime32()
またはの1 つの関数しかありませんtime64()
。
しばらく調べてみると、libc のせいではなく、実はカーネルに問題があることがわかりました。
libc が現在の時刻を取得するには、システム コールを実行する必要があります: ( Source )
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
システムコールは次のように定義されます: ( Source )
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
関数は次のように をget_seconds()
返します: ( Source )unsigned long
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
そしてtimekeeper.xtime_sec
実際には64ビットです:(ソース)
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
C の知識があれば、 のサイズunsigned long
が実際には実装に依存することがわかります。ここにある私の 64 ビット マシンでは、64 ビットです。しかし、私の 32 ビット マシンでは 32 ビットです。一部の 32 ビット実装では 64 ビットになる可能性がありますが、保証はありません。
一方、u64
は常に 64 ビットであるため、カーネルは基本的に 64 ビット型で時間を追跡します。これを として返す理由はunsigned long
、64 ビット長であることが保証されていないため、私には理解できません。
結局、libc がtime_t
64 ビットの値を保持することを強制したとしても、何も変わりません。
アプリケーションをカーネルに深く結び付けることができますが、それだけの価値はないと思います。
time64()/time32()
標準ライブラリには関数は含まれていません。
time32_t/time64_t
標準ヘッダーでは、定義は想定されていません。
time_t
として定義さtime.h
れtypedef __time_t time_t
ます。
長い一連の再定義をたどると、 が__time_t
32 ビット マシンでは 32 ビット、64 ビット マシンでは 64 ビットとして定義されていることがわかります。
あなたが本当にこれを必要とするならば、なぜあなた自身を転がしてみませんか?
typedef int32_t my_time32;
typedef int64_t my_time64;
my_time32 get_mytime32() {
if (sizeof(time_t) == sizeof(my_time32))
return time(NULL);
else {
/* Check for overflow etc. here... */
return (my_time32)(time(NULL));
}
}
同様にget_mytime64()
。
オーバーフローを気にしない場合は、return time(NULL);
Cの暗黙的な数値変換のおかげで、両方の関数で単純に機能します。