Я предполагаю, что из-за того, что вы сказали, что 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, вы будете читать лишние биты, но это не имеет значения; эти биты являются «неважными» битами. Затем, чтобы прочитать значение time_t из этого uint64_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
Какой код для 'setValue' и' getValue'? –
Я просто передаю refernce to tt, который получает обновление в getValue. setValue - это api, у меня есть, к которому у меня нет доступа. Но я уверен, что он делает правильные вещи. Я думаю, что это мое кастинг, который сломан. –
«Что такое код», @Mark просит вас обновить свой вопрос, включив в него фактический код. – Nemo