1

我正在尝试通过执行以下操作将 time_t 转换为 in64_t。

time_t t = 1349388030;

我有一个 API。

SomeObj.setValue(const int64_t)            // Sets the value of SomeObj to the passed argument
SomeObj.getValue(int64_t & value) const    // Returns the value

然后我执行以下操作。

SomeObj.setValue(t)
int64_t tt;
SomeObj.getValue(tt)
assert (tt == t)                           // Fails where tt = 109726776

任何人都可以帮助正确的铸造程序吗?

编辑:

这是我使用 set_value 的方式在我的代码中的错误

4

3 回答 3

4

在 3 种情况下,您必须担心从一种整数类型转换为另一种:

  1. 你从一个大整数转换为一个小整数。我有理由相信,sizeof(int64_t) >= sizeof(time_t)所以这不应该是一个问题。
  2. 您将无符号类型转换为有符号类型,并且值超出了有符号类型的范围。再次不太可能,因为 1349388030 小于 2^31。
  3. 您将有符号类型转换为无符号类型,并且值为负。不适用于这里。

我不认为问题出在你的选角上。

于 2012-10-04T22:31:02.310 回答
2

我从您所说的假设 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
于 2012-10-05T15:13:04.673 回答
0

我看不出你的代码有问题。在某些平台time_t上已经是int64_t. 我认为你的问题在其他地方。里面是什么SomeObj

于 2012-10-04T22:21:41.347 回答