摆脱"warning C4267 possible loss of data"的最佳策略是什么?



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

我们最终得到了大量的;

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

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

我知道

为什么警告有意义,我知道为什么发出警告以及如何修复它。但是,在这个具体的例子中,我们过去从未遇到过容器尺寸超过unsigned int的最大值的情况。因此,当代码移植到 64 位环境时,没有理由出现此问题。

我们讨论了抑制这些嘈杂警告的最佳策略(它们可能会隐藏我们将错过的相关警告),但我们无法就专有策略做出决定。

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

1. 使用static_cast

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

2. 将unsigned int替换为size_t

这肯定更难,因为上面示例中unsigned int size对象可以添加到其他函数,保存为类属性,然后删除一行警告最终可能会导致进行数百次代码更改......

3. 禁用警告

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

4. 定义一个"安全强制转换"*函数并使用它

像这样:

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"可能是一个很好的答案。

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

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

它进入意图......你得到vsizesize有一个类型。如果从一开始就使用正确的类型,这将不是问题。

如果以后需要将该值作为另一种类型,请对其进行转换;然后safe_cast<>是一个很好的替代方法,它包括运行时边界检查。

选项 6.使用auto

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

auto size = v.size();

并让编译器为您完成艰苦的工作。

IFF 你有时间压力来免费获得代码警告,我最初会禁用警告——你的代码曾经使用它,恕我直言,在你分配给 32 位大小的情况下,你极不可能超过它。(集合中的 4G 值 - 我怀疑这在正常应用程序中会飞。

话虽如此,对于集合以外的情况,警告当然有其优点,因此迟早要尝试启用它。

其次,在启用它并修复代码时,我的优先级是:

  • 对于值未进一步缩小的本地变量,请使用 auto(或 size_t C++11 之前)。
  • 当需要缩小范围,如果您可以证明将其引入团队的开销是合理的,请使用您的safe_cast。(学习、执行等)
  • 否则只需使用static_cast

    我不认为这是收藏的问题。如果您了解相反的情况,那么您的收藏将永远不会超过4G物品。恕我直言,对于任何正常的现实世界用例,在集合中拥有如此多的数据是没有意义的。(这并不是说可能没有需要如此大数据集的古怪情况,只是您会知道何时会出现这种情况。

    对于您实际上没有缩小集合计数而是缩小其他数字的情况,缩小无论如何都可能有问题,因此您将在那里适当地修复代码。

最新更新