c++ - What's the best strategy to get rid of "warning C4267 possible loss of data"? -
i ported legacy code win32 win64. not because win32 object size small our needs, because win64 more standard , wish port our environments format (and use 3rd party libs offering better performance in 64bits in 32bits).
we end tons of;
warning c4267: 'argument': conversion 'size_t' '...', possible loss of data
mainly due code like: unsigned int size = v.size();
v
stl container.
i know why warning makes sense, know why issued , how fixed. however, in specific example, never experienced cases container size exceeded unsigned int
's max value in past.... there no reason problem appear when code ported 64bits environment.
we had discussions on best strategy supress noisy warnings (they may hide relevant 1 miss), not make decision on apropriate strategy.
so i'm asking question here, best recommended strategy?
1. use static_cast
use static_cast
. unsigned int size = static_cast<unsigned int>(v.size());
. don't "like" because loose 64bits capability store huge amount of data in container. our code never reached 32bits limit, appears safe solution...
2. replace unsigned int
size_t
that's harder unsigned int size
object in example above pased other functions, saved class attribute , removing one-line warning end in doing hundreds of code change...
3. disable warning
that's bad idea disable warning in case uint8_t size = v.size()
cause loss of data....
4. define "safe cast"* function , use it
something like:
template <typename from, typename 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 unsigned signed cast (int64_t uint32_t), test below better: assert(value == static_cast<from>(static_cast<to>(value))); // verify don't loose information! // or throw.... return static_cast<to>( value ); }
5. other solutions welcome...
"use solution 1 in case 2 in case" answer.
use correct type (option 2) - function/interface defines type you, use it.
std::size_t size = v.size(); // given vector<>::size_type size_t // or more verbose decltype(v)::size_type size = v.size();
it goes intent... getting size
of v
, size
has type. if correct type had been used beginning, not have been problem.
if require value later type, transform then; safe_cast<>
alternative includes runtime bounds checking.
option 6. use auto
when use size = v.size()
, if not concerned type is, use correct type,
auto size = v.size();
and let compiler hard work you.
Comments
Post a Comment