приведение uint32_t к uint64_t приводит к другому значению?

Использование Visual Studio 2015 C ++, обновление 14.0.25431.01 3. В моем коде неожиданное поведение. Скомпилируйте и запустите с 64-битной версией:

#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 дают мне ожидаемые числа.

РЕДАКТИРОВАТЬ: я обновил свой код с более простой версией, которая имеет ту же проблему. Также, Я только что отправил отчет об ошибке.

14

Решение

Я мог бы воспроизвести это на VS2010, и непосредственная причина заключается в следующем:

add ebx, 5BD1E995h  ; this is x
add rdi, 5BD1E995h  ; this is a 64bit version of x

Так как это 64-битное дополнение, оно просто переносится в старшие 32 бита. По крайней мере, это имеет больше смысла, чем вызывать 64-битное умножение, это может быть ключевой случай в исключении индукционных переменных, но это всего лишь предположение.

Также забавно, что он даже не сохраняет актерский состав, неправильно компилируя его. Правильное значение находится прямо в rbx,

7

Другие решения

Похоже, что это исправление устраняет проблему, по крайней мере, для VS 2015:

https://support.microsoft.com/en-us/help/3207317/visual-c-optimizer-fixes-for-visual-studio-2015-update-3

Но, похоже, VS 2008, 2010, 2013 все еще подвержены этой ошибке.

Источники:

1

По вопросам рекламы [email protected]