Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

casting uint32_t to uint64_t results in different value?

Using Visual Studio 2015 C++, 14.0.25431.01 Update 3. I have unexpected behavior in my code. Compile and run with 64bit, 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;
    }
}

I expect that a and b have the same value, but when I run this I get this output:

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

It looks like the compiler replaces the 32bit multiplication with a 64bit multiplication. Is it allowed to do that, or is this a compiler bug? Both g++ and clang give me the numbers that I'd expect.

EDIT: I've update my code with a simpler version that has the same problem. Also, I've just submitted a bug report.

like image 395
martinus Avatar asked Feb 28 '17 14:02

martinus


2 Answers

I could reproduce this on VS2010, and the immediate cause is this:

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

Since it's a 64bit addition, it will just carry into the high 32 bits. This at least makes more sense than conjuring up a 64bit multiplication, it might be a corner case in induction variable elimination but that's just speculation.

Also fun is that it doesn't even save a cast by miscompiling it. The correct value is right there in rbx.

like image 92
harold Avatar answered Oct 22 '22 10:10

harold


It appears that this hotfix fixes the issue, at least for VS 2015:

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

But it seems that VS 2008, 2010, 2013 are still affected by this bug.

Sources:

  • https://www.reddit.com/r/cpp/comments/5wwmi2/visual_studio_2015_compiler_bug_64bit_instead_of/dedfw27/
  • https://www.reddit.com/r/cpp/comments/5wwmi2/visual_studio_2015_compiler_bug_64bit_instead_of/dedzh5g/
like image 1
martinus Avatar answered Oct 22 '22 11:10

martinus