あなたが言ったことから、SomeObjは実際には時間が何であるかを気にしない、それはあなたが時間を保存する必要がある単なるストレージコンテナであると仮定しています。また、あなたのユースケースでは、あなたが保存するフォーマットが何であれ、あなたの時間はポータブルである必要はありません、そして保存された時間はそれらが生成されたのと同じシステムで常に使用されます。これらの仮定のいずれかが当てはまらない場合、キャストは問題の適切な解決策ではありません(そして、以下でより適切な解決策について説明します。についての説明を参照してくださいlocaltime()
)。
time_t
内に値を格納するにはint64_t
変数、もちろんsizeof(time_t)はsizeof(int64_t)以下でなければならないので、コードはそのためのアサーションチェックを行う必要があります。これで、time_tをint64_tに割り当てることはできません(すべてのシステムではなく、ほとんどのシステムで問題なく機能します)。time_tが浮動小数点型の場合、変換時と変換時に精度が低下する可能性があるためです。 time_tに戻ると、同じ値ではない可能性があります(ただし、正しい値に「近い」場合があります)。重要なのは、移植可能なコードの場合、time_t値の形式について何も仮定できないということです。ここで繰り返しますが、以下のコードは移植可能ですが、ソリューションはそれ自体が移植可能な時間値を生成しません。つまり、あるシステムでtime_t値を生成し、SomeObjがその値を別の「システム」に送信する場合 (同じプロセッサ上でも、別のコンパイラによってコンパイルされた場合でも)他のシステムで解釈する場合、他のシステムは値を同じように解釈する場合としない場合があります。そのためには、time_tを離散数に変換する必要があります。localtime()
または、その構造を他のシステムにlocaltime_r()
転送し、を介してそのシステムのtime_t形式に変換します。mktime()
いずれにせよ、解釈に依存しない方法でtime_t値をuint64_tに詰め込むには、time_t値の場所からビットをuint64_tとして読み取る必要があります。time_tがuint64_tほど広くない場合は、余分なビットを読み込みますが、それは問題ではありません。それらのビットは「ドントケア」ビットです。次に、そのuint64_tからtime_t値を読み取るには、uint64_tの場所からtime_tとしてビットを読み取る必要があります。つまり、ソース変数のアドレスを取得し、それを宛先タイプのポインターとしてキャストしてから、逆参照します。タイプのサイズが一致しない場合は、宛先変数に余分なガベージビットを読み込むか、とにかくガベージビットであったと思われるビットを失います。これがコードでそれを行う方法です...
#include <time.h>
#include <assert.h>
struct SomeClass
{
int64_t i64;
void setValue(const int64_t v) { i64 = v; }
void getValue(int64_t& v) const { v = i64; }
};
#if 0 // Set to 1 for C style casting, or 0 for C++ style casting.
int main()
{
assert (sizeof(int64_t) >= sizeof(time_t));
// ...fundamental, otherwise nothing else has any hope of working
SomeClass SomeObj;
time_t t = 1349388030;
int64_t i = *((int64_t*)&t);
SomeObj.setValue(i);
int64_t ii;
time_t tt;
SomeObj.getValue(ii);
tt = *((time_t*)&ii);
assert (tt == t);
}
#else
int main()
{
assert (sizeof(int64_t) >= sizeof(time_t));
// ...fundamental, otherwise nothing else has any hope of working
SomeClass SomeObj;
time_t t = 1349388030;
int64_t i = *reinterpret_cast<int64_t*>(&t);
SomeObj.setValue(i);
int64_t ii;
time_t tt;
SomeObj.getValue(ii);
tt = *reinterpret_cast<time_t*>(&ii);
assert (tt == t);
}
#endif