Q:

(Visual C++ v141) Bitwise function compiling incorrectly

Using Visual Studio Enterprise 2017 version 15.1 (26403.7) on toolset v141. 
The following code seems to compile incorrectly.
#define GMASK(rangeStart, rangeEnd) ((1 << (rangeEnd - rangeStart + 1)) - 1)
uint32_t _gmask(uint32_t rangeStart, uint32_t rangeEnd)
{
    return ((1 << (rangeEnd - rangeStart + 1)) - 1);
}

int main()
{
    cout << bitset<32>(GMASK(0, 31)) << endl;
    cout << bitset<32>(_gmask(0, 31)) << endl;

    return 0;
}

In Visual Studio the output is
11111111111111111111111111111111
00000000000000000000000000000000

However in gcc the output is
11111111111111111111111111111111
11111111111111111111111111111111

Why is there a difference in the output when it's the same code?

A:

It's undefined behavior.
In your code, when computing _gmask(0, 31), the value 232 is used. That's already outside the range of uint32_t, which could range from 0 to 232 - 1.
From C++14 5.8 Shift operators:

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable
  in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

