c++ - 带有 Visual Studio 2005 的 volatile unsigned __int64 行为异常

标签 c++ visual-studio-2005 64-bit volatile

我有一个服务器,它使用一个全局变量来存储下一个可用的唯一 ID。

最初,这被定义为 unsigned long g_nextUniqueId volatile;我正在将所有 ID 更改为 64 位整数,因此这一行更改为 unsigned __int64 g_nextUniqueId volatile;

只有两段代码直接访问这个变量。

第一个是在服务器启动时填充它,它非常简单,它只是运行一个 SQL 查询,检索一个值并将它存储到一个 unsigned __int64 lastId 中。 ,然后有一个语句将其存储在全局中,g_nextUniqueId = 1 + lastId; .

另一个是检索和使用下一个可用 ID 的函数。这是一个单行函数,return (unsigned __int64)InterlockedIncrement64((LONGLONG*)&g_nextUniqueId);

问题似乎是有两个不同的g_nextUniqueId变量,由于缺少更好的术语,在初始化函数中。

g_nextUniqueId被填充,正确的值被写入错误的地址。根据调试器,&g_nextUniqueId 不是值写入的地址。如果我存储 &g_nextUniqueId在另一个变量中,作为 void* , &g_nextUniqueId 的值和 void* 是等效的。 void*值实际上是正确的地址。这只适用于这个函数;在任何其他函数中,void*&g_nextUniqueId是等价的。

void* somePtr = (void*)&g_nextUniqueId;
Output(ToString(somePtr) + " " + ToString(&g_nextUniqueId));
// Output will be something "0x01BAF1D8 0x0012EFA4"
// 0x0012EFA4 is on or near the bottom of the stack, I believe.

稍后,当我去检索下一个可用 ID 时,g_nextUniqueId InterlockedIncrement64 actions on 将是正确的,其值为 0,因为初始值被写入了错误的地址。

希望这是有道理的(即问题描述)。

为什么是g_nextUniqueId = 1 + lastId;行写入错误的地址?如果我将类型改回 unsigned long , 代码工作正常。

目前,我能想出的唯一解决方案是复制 &g_nextUniqueIdvoid*然后将其转换回 volatile unsigned __int64和分配。

最佳答案

听起来您需要进行完全重新编译。

当您对多个翻译单元中使用的类型进行更改时,通常会出现这种情况。有时依赖性检查器会感到困惑。

关于c++ - 带有 Visual Studio 2005 的 volatile unsigned __int64 行为异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4659571/

相关文章:

c++ - 使用 COM 接口(interface)而不静态链接到库

c++ - 删除指向自动变量的指针

c++ - C++ 游戏的动态数据处理

c# - 无效的表达式项 '>'

x86 - MASM 中 x64 和 x86 模式的区别

c# - 访问 COM 时,如何在 x86 和 x64 下编写安全的 C# 代码?典型的陷阱?

c++ - 素数筛分错

c++ - Windows XP 下 CAtlStringMgr::GetInstance 崩溃

visual-studio-2005 - 在 VS2005 中使用 Windows 7 和 DirectX SDK

visual-studio-2008 - 有没有人已经完成了使用 VS2008 构建 STLPort 和/或使用 VS2005 构建 x64 的工作?