什么是最好的策略摆脱“警告C4267可能的数据丢失”? [英] What's the best strategy to get rid of "warning C4267 possible loss of data"?

查看:164
本文介绍了什么是最好的策略摆脱“警告C4267可能的数据丢失”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一些旧代码从win32移植到win64。不是因为win32对象的大小对我们的需求太小,而是因为win64现在更标准,我们希望将所有环境移植到这种格式(我们还使用一些第三方库,在64位中提供比32位更好的性能) 。

I ported some legacy code from win32 to win64. Not because the win32 object size was too small for our needs, but just because win64 is more standard now and we wish to port all our environments to this format (and we also use some 3rd party libs offering better performance in 64bits than in 32bits).

我们最终以吨为单位;

We end up with tons of;


警告C4267:'参数':从'size_t'转换为'...',可能会丢失数据

warning C4267: 'argument': conversion from 'size_t' to '...', possible loss of data

主要是由于代码: unsigned int size = v.size(); 其中 v 是STL容器。

Mainly due to code like: unsigned int size = v.size(); where v is a STL container.

我知道为什么警告有意义,我知道为什么它被发出,以及如何可以修复。然而,在这个具体的例子中,我们从来没有遇到容器大小超过 unsigned int 的过去的最大值的情况....所以没有理由

I know why the warning makes sense, I know why it is issued and how it could be fixed. However, in this specific example, we never experienced cases where the container size exceeded unsigned int's max value in the past.... so there will be no reason for this problem to appear when code is ported to 64bits environment.

我们讨论了什么是最好的策略来抑制这些嘈杂的警告(他们可能会隐藏一个相关的警告

We had discussions on what would be the best strategy to supress those noisy warnings (they may hide a relevant one we will miss), but we could not make a decision on the apropriate strategy.

所以我在这里问这个问题,最好的推荐策略是什么?

So I'm asking the question here, what would be the best recommended strategy?

1。使用 static_cast

1. Use a static_cast

使用 static_cast 。 do unsigned int size = static_cast< unsigned int>(v.size()); 。我不喜欢,因为我们松开了64位的能力,在一个容器中存储大量的数据。但因为我们的代码从未达到32位的限制,所以这似乎是一个安全的解决方案...

Use a static_cast. Do unsigned int size = static_cast<unsigned int>(v.size());. I don't "like" that because we loose the 64bits capability to store a huge amount of data in a container. But as our code never reached the 32bits limit, so this appears to be a safe solution...

2。将 unsigned int 替换为 size_t

2. Replace unsigned int by size_t

这肯定比较难,因为在上面的例子中, unsigned int size 对象可以改为其他函数,保存为类属性,然后删除一行警告可能会在做数百的代码更改...

That's definitely harder as unsigned int size object in the example above could be pased to other functions, saved as class attribute and then removing a one-line warning could end up in doing hundreds of code change...

3。停用警告

这可能是一个非常糟糕的主意,因为它也会在这种情况下禁用警告 uint8_t size = v.size ()这绝对可能导致数据丢失....

That's most likely a very bad idea as it would also disable warning in this case uint8_t size = v.size() which is definitely likely to cause loss of data....

4。定义安全投射*函数并使用

4. Define a "safe cast"* function and use it

某事 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。欢迎使用其他解决方案...

在这种情况下使用解决方案1,但在这种情况下使用解决方案2可能是一个很好的答案。

"Use solution 1 in this case but 2 in this case" could perfectly be a good answer.

推荐答案

使用正确的类型(选项2) - 函数/接口为您定义该类型,使用它。

Use the correct type (option 2) - the function/interface defines that type for you, use it.

std::size_t size = v.size(); // given vector<>::size_type is size_t
// or a more verbose
decltype(v)::size_type size = v.size();

并且 size 有一个类型。c $ c> size of v 如果从头开始使用了正确的类型,这不会是一个问题。

It goes to the intent... you are getting the size of v and that size has a type. If the correct type had been used from the beginning, this would not have been a problem.

如果以后要求该值作为另一个类型, safe_cast<> 是一个很好的选择,包括运行时边界检查。

If you require that value later as another type, transform it then; the safe_cast<> is then a good alternative that includes the runtime bounds checking.

。使用 auto

Option 6. Use auto

使用 size = v.size ),如果你不关心类型是什么,只是你使用正确的类型,

When you use size = v.size(), if you are not concerned what the type is, only that you use the correct type,

auto size = v.size();

让编译器为你做艰苦的工作。

And let the compiler do the hard work for you.

这篇关于什么是最好的策略摆脱“警告C4267可能的数据丢失”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆