I ported some legacy code from win32 to win64. Not because the size of the win32 object was too small for our needs, but only because win64 is now more standard, and we want to transfer all our environments to this format (and we also use some third-party libraries that offer better performance in 64 bits, than 32 bits).
As a result, we get tons;
warning C4267: 'argument': conversion from 'size_t' to '...', possible data loss
Mostly because of code like: unsigned int size = v.size(); where v is the STL container.
I know why the warning makes sense; I know why it is issued and how it can be fixed. However, in this particular example, we never faced situations when the size of the container exceeded the unsigned int max value in the past .... therefore, there will be no reason for this problem when porting code to a 64-bit environment.
We had discussions about what would be the best strategy to suppress these noise alerts (they might hide the corresponding one that we will skip), but we could not decide on the appropriate strategy.
So, I ask the question here, what would be the best recommended strategy?
1. Use static_cast
Use static_cast . Make unsigned int size = static_cast<unsigned int>(v.size()); . I donβt βloveβ because we lose the ability to 64 bits to store a huge amount of data in the container. But since our code never reached the limit of 32 bits, so this seems like a safe solution ...
2. Replace unsigned int with size_t
This is definitely more complex than the unsigned int size object in the above example can be ported to other functions stored as a class attribute, and then deleting a single-line warning can result in hundreds of code changes ...
3. Disable warning
This is most likely a very bad idea, as it will also disable the warning in this case uint8_t size = v.size() , which, of course, can lead to data loss ....
4. Define the "safe casting" function * and use it
Something like :
template <typename From, typename To> To safe_cast( const From& value ) { //assert( value < std::numeric_limits<To>::max() && value > std::numeric_limits<To>::min() ); // Edit 19/05: test above fails in some unsigned to signed cast (int64_t to uint32_t), test below is better: assert(value == static_cast<From>(static_cast<To>(value))); // verify we don't loose information! // or throw.... return static_cast<To>( value ); }
5. Other solutions are welcome ...
"Use solution 1 in this case, but 2 in this case" perfectly might be a good answer.