我正在使用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值?
答案 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));
这显然不是线程安全的(编辑:我想您可以将其设置为线程本地的),并且仍然存在相同的可用性问题,所以我会避免使用它。但这会起作用。