使用Visual Studio 2005的volatile unsigned __int64表现得很奇怪

时间:2011-01-11 15:56:51

标签: 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_nextUniqueIdvoid*的值不等于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动作将是正确的,其值为0,因为初始值已写入错误的地址。

希望这有意义(问题描述,即)。

为什么g_nextUniqueId = 1 + lastId;行写错了地址?如果我将类型更改回unsigned long,则代码可以正常工作。

目前,我能提出的唯一解决方案是将&g_nextUniqueId复制到void*,然后将其转发回volatile unsigned __int64并进行分配。

1 个答案:

答案 0 :(得分:2)

听起来你需要完全重新编译。

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