0

I am trying to wrap my head around a warning I get from MSVC. From what I can tell, the warning seems to be bogus, but I would like to be sure.

I am trying to convert an off_t to an offset in an OVERLAPPED. Given an off_t named offset and an OVERLAPPED named overlapped, I am trying the following:

overlapped.Offset = static_cast<DWORD>(offset);
if constexpr(sizeof(offset) > 4) {
    overlapped.OffsetHigh = static_cast<DWORD>(offset >> 32);
}

MSVC complains about the bitshift, pretending the shift count is either negative or too big. Since it's clearly not negative - and even MSVC should be able to tell that - it must think it's too big.

How could it be too big? The code in question is only compiled if the size of an off_t is greater than 4. It must therefore be at least 5 bytes (but probably 8), and given 8 bits to the byte meaning a minimum of 40 bits, which is more than 32.

What is going on here?

Martijn Otto
  • 878
  • 4
  • 21

1 Answers1

1

Could it be the assignment into overlapped.OffsetHigh, and not your explicit shift, that is causing the warning? The following code generates the same warning on VS2015 compiling for x86 32-bit:

struct Clump
{
    unsigned int a : 32;
    unsigned int b : 32;
    unsigned int c : 32;
};

unsigned int x = 0;
unsigned int y = 0;
unsigned int z = 0;

Clump clump = { x, y, z }; // This is line 1121.

1>E.cpp(1121): warning C4293: '<<': shift count negative or too big, undefined behavior

But removing the bit-fields, there is no warning:

struct Clump
{
    unsigned int a;
    unsigned int b;
    unsigned int c;
};

unsigned int x = 0;
unsigned int y = 0;
unsigned int z = 0;

Clump clump = { x, y, z }; // No warning.