C++ Warnings – Usefulness of Compiler Warning for 64bit to 32bit `size_t` Truncation

cvisual c++warnings

I have been looking at VC++'s C4267:

Compiler Warning (level 3) C4267

'var' : conversion from 'size_t' to 'type', possible loss of data

The compiler detected a conversion from size_t to a smaller type.

To fix this warning, use size_t instead of type. Alternatively, use an
integral type that is at least as large as size_t.

I have been looking at this, and – maybe unsurprisingly – when converting a 32 bit code base to 64 bit, there a lots of these errors, mainly wrt. vector.size() etc.

Notes:

  • /W3 is the default level in VC++ – so this is a default warning.
  • The warning is triggered only for size_t — even though it is "just" a typedef for unsigned __int64, if you use uint64 directly, the warning isn't triggered as far as I can tell.

Now, this made me wonder, purely on a conceptual level, does this compiler warning actually make any sense for the 64bit size_t => 32bit type?

size_t, is a typedef used for sizes. Mostly of std collections etc. in lower level code for raw memory sizes.

As such, truncating these values from 64bit to 32bit will produce erroneos results IFF the size in question > 4G. That's a lot, I mean really a lot for real world data counts.

Truncating to 16 bit or 8 bit certainly deserves a warning, but this isn't handled separately here. As such, I have the impression that this default warning provides more noise than value to the majority of developers.

Does this warning as-is provide some real benefit that I'm missing here? Or is it really to simplistic? Maybe/possibly I'm missing an important use case for size_t?

Best Answer

The warning is triggered only for size_t -- even though it is "just" a typedef for unsigned __int64, if you use uint64 directly, the warning isn't triggered as far as I can tell.

But uint64_t didn't change size when you moved to 64 bits, and size_t did.

The compiler isn't warning you just because this is a narrowing conversion, although it might on another level.

It's warning you because code that previously used uint32_t for size_t, has now silently changed to using uint64_t instead, and this might cause surprising bugs with no visible change in the code.