如何将unsigned long转换为64位的time_t

时间:2018-08-08 16:28:16

标签: c++ casting 64-bit

我正在使用MSVC6(Visual Studio 98)在C ++中以32位这样调用本地时间:

localtime((time_t *)&FileData.LastAccessDateTime)

FileData.LastAccessDateTime是无符号的长整数,可以编译并以32位运行。我现在正在使用VS2017转换代码。它可以在64位上很好地编译,但是在运行时在localtime b / c内崩溃,传递给localtime的高位双字充满了垃圾。我知道我可以将FileData.LastAccessDateTime分配给temp time_t变量,然后获取其地址。但是我想在不创建局部临时变量的情况下解决此问题,因为我必须在代码的其他100个地方解决此问题。我尝试将FileData.LastAccessDateTime强制转换为__int64,但出现编译错误,说:“&”需要左值。 b / c FileData.LastAccessDateTime在内存中有一个物理地址,这对我来说似乎很奇怪,我只是在更改查看方式(或者我认为)。

那么,如何在一行上更改此强制转换,以正确地将无符号的long转换为time_t值?

1 个答案:

答案 0 :(得分:1)

问题的核心是我们需要提供一个指向localtime的8字节大小的存储位置的指针,而FileData.LastAccessDateTime处的指针只有4个字节。因此,我们需要在其他地方抢占一些空间。

选项1: 8个字节的空间将位于上。应该这样做:

localtime(std::make_unique<time_t>(FileData.LastAccessDateTime).get());

unique_ptr处理堆分配和清理。当然,这每次都会花费您一个内存分配。可以吗?您可以决定。

选项2: 8个字节的空间将位于堆栈上。这里没有函数本地对象的方法,但是您可以将其包装到便利函数中(希望可以在所有这100个地方使用):

struct tm * localtime64comp(uint32_t* timer32)
{
  uint64_t timer64 = timer32;
  return localtime(timer64);
}

// ...

localtime64comp((time_t *)&FileData.LastAccessDateTime);

如果您无法在所有地方都可以使用此功能,那么这似乎是不可行的。

选项3:使用全局(ugh)作为空间。

uint64_t LOCALTIME_COMP;

// ...

localtime(&(LOCALTIME_COMP = FileData.LastAccessDateTime));

这显然不是线程安全的(编辑:我想您可以将其设置为线程本地的),并且仍然存在相同的可用性问题,所以我会避免使用它。但这会起作用。