2017-02-28 18 views
14

Korzystanie z Visual Studio 2015 C++, 14.0.25431.01 Aktualizacja 3. Mam nieoczekiwane zachowanie w moim kodzie. Skompilować i uruchomić z 64bit, zwolnij:rzutowanie uint32_t na uint64_t daje inną wartość?

#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; 
    } 
} 

Spodziewam się, że a i b mają taką samą wartość, ale gdy uruchomię to uzyskać ten wynik:

4224838037 32bit 
4224838037 64bit 
4154708778 32bit 
8449676074 64bit 

wygląda na to, że kompilator zastępuje Mnożenie 32-bitowe z mnożeniem 64-bitowym. Czy wolno to zrobić, czy jest to błąd kompilatora? Zarówno g ++, jak i clang dają mi liczby, których bym się spodziewał.

EDIT: mam zaktualizować kod z prostszej wersji, która ma ten sam problem. Ponadto, I've just submitted a bug report.

+0

Nie repro z gcc i brzękiem. To absolutnie nie powinno się zdarzyć. Edycja: również bez repro z VS na rextester. –

+0

Nie można odtworzyć przy użyciu kompilatora mingw i Visual Studio. – SingerOfTheFall

+0

jakiej wersji VS używasz? Czy skompilowałeś Release 64bit? – martinus

Odpowiedz

1
7

mogę odtworzyć to na VS2010, a bezpośrednią przyczyną jest to:

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

Ponieważ jest to dodatek 64bit, to będzie po prostu nosić do wysokich 32 bitów. To przynajmniej ma więcej sensu niż wywoływanie mnożenia 64-bitowego, może to być przypadek rogu w eliminacji zmiennej indukcyjnej, ale to tylko spekulacja.

także zabawy jest to, że nawet nie zapisać oddanych przez miscompiling go. Prawidłowa wartość znajduje się właśnie tutaj: rbx.

+1

Dlaczego używa 'add' do mnożenia? W każdym razie [wydaje się nie pojawiać w CL19] (https://godbolt.org/g/i6Y9is) już. Mogę tylko znaleźć 'imul' z 1540483477 –

+2

Myślę, że kompilator stara się być inteligentny i zastępuje pętlę od 0 do 50, gdzie licznik pętli jest mnożony przez stałą, z samą dodawaniem stałej. – martinus

Powiązane problemy