volatile unsigned __int64 с Visual Studio 2005 ведет себя странно - PullRequest
0 голосов
/ 11 января 2011

У меня есть сервер, который использует глобальную переменную для хранения следующего доступного уникального идентификатора.

Первоначально это было определено как unsigned long g_nextUniqueId volatile; Я меняю все идентификаторы на 64-битные целые числа, поэтомуэта строка была изменена на unsigned __int64 g_nextUniqueId volatile;

Есть только два фрагмента кода, которые напрямую обращаются к этой переменной.

Первый - заполнить ее при запуске сервера, это очень просто, простозапускает SQL-запрос, получает значение и сохраняет его в unsigned __int64 lastId, а затем есть оператор для его сохранения в глобальном g_nextUniqueId = 1 + lastId;.

Другой - это функция для получения и использования следующегодоступный идентификатор.Это однострочная функция, 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.

Позже, когда я пойду, чтобы получить следующий доступный идентификатор, g_nextUniqueId, на который действует InterlockedIncrement64, будетправильный, который имеет значение 0, так как начальное значение было записано по неправильному адресу.

Надеюсь, это имеет смысл (то есть описание проблемы).

Почему g_nextUniqueId = 1 + lastId; запись строки не по адресу?Если я поменяю тип обратно на unsigned long, код будет работать правильно.

На данный момент единственное решение, которое я могу придумать, это скопировать &g_nextUniqueId в void* и затем привести его обратно кvolatile unsigned __int64 и присвоение.

1 Ответ

2 голосов
/ 11 января 2011

Звучит так, будто вам нужно выполнить полную перекомпиляцию.

Часто это происходит, когда вы вносите изменения в тип, используемый в нескольких единицах перевода.Иногда проверка зависимостей запутывается.

...