Ответ 1
Похоже, это исправление устраняет проблему, по крайней мере, для VS 2015:
Но похоже, что VS 2008, 2010, 2013 все еще затронуты этой ошибкой.
Источники:
Использование Visual Studio 2015 С++, 14.0.25431.01 Обновление 3. У меня неожиданное поведение в моем коде. Скомпилируйте и запустите с 64-битным, Release:
#include <iostream>
#include <stdint.h>
int main(int, char**) {
for (uint32_t i = 1; i < 3; ++i) {
uint32_t a = i * 0xfbd1e995;
uint64_t b = a;
std::cout << a << " 32bit" << std::endl;
std::cout << b << " 64bit" << std::endl;
}
}
Я ожидаю, что a
и b
имеют одинаковое значение, но когда я запустил это, я получаю этот вывод:
4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit
Похоже, что компилятор заменяет 32-битное умножение на 64-битное умножение. Разрешено ли это делать, или это ошибка компилятора? И g++, и clang дают мне числа, которые я ожидаю.
EDIT: я обновляю свой код с более простой версией, которая имеет ту же проблему. Кроме того, Я только что отправил отчет об ошибке.
Похоже, это исправление устраняет проблему, по крайней мере, для VS 2015:
Но похоже, что VS 2008, 2010, 2013 все еще затронуты этой ошибкой.
Источники:
Я мог бы воспроизвести это на VS2010, и непосредственной причиной этого является следующее:
add ebx, 5BD1E995h ; this is x
add rdi, 5BD1E995h ; this is a 64bit version of x
Так как это 64-битное дополнение, оно просто будет содержать 32 бита. Это, по крайней мере, имеет больше смысла, чем создание 64-битного умножения, это может быть угловой случай исключения индукционной переменной, но это просто предположение.
Также интересно, что он даже не сохраняет бросок, ошибочно комментируя его. Правильное значение находится прямо в rbx
.