什么是摆脱“警告C4267可能的数据丢失”的最佳策略?

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

我们结束了吨;

警告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位的function来将大量的数据存储在一个容器中。 但是,因为我们的代码从来没有达到32位的限制,所以这似乎是一个安全的解决scheme…

2.用size_treplaceunsigned int

这是绝对困难的,因为在上面的例子中, unsigned int size对象可以用于其他函数,保存为class属性,然后删除单行警告可能会导致数百个代码更改…

3.禁用警告

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

4.定义一个“安全演员”*function并使用它

类似于 :

 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.其他解决scheme,欢迎…

“在这种情况下使用解决scheme1,但在这种情况下使用解决scheme1”可能是一个很好的答案

使用正确的类型(选项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(); 

它的意图是…你得到的size ,这个size有一个类型。 如果从一开始就使用正确的类型,这不会是一个问题。

如果你以后需要这个值作为另一个类型,那么转换它; 那么safe_cast<>是包含运行时边界检查的一个很好的选择。

选项6.使用auto

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

 auto size = v.size(); 

让编译器为你做好工作。

IFF你有时间压力免费的代码警告,我会最初禁用警告 – 你的代码用于这个工作,这是,恕我直言, 不可能的情况下,你指定一个32位的大小,你会超过它。 (一个集合中有4个G值 – 我怀疑它会在正常的应用程序中飞行。)

也就是说,对于集合以外的情况,这个警告肯定是有好处的,所以迟早要试一试。

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

  • 在值不会进一步缩小的地方使用auto (或size_t pre C ++ 11)。
  • 如果您需要缩小范围,请使用safe_cast如果您可以证明将其引入团队的开销。 (学习,执行等)
  • 否则,只需使用static_cast

    我不认为这是收藏的问题。 如果知道更好的相反,你的收藏将永远不会超过4G的项目。 恕我直言,这只是没有任何意义的是,在任何正常的现实世界的用例集合中有这么多的数据。 (这并不是说你可能不需要这么庞大的数据集,只是在这种情况下你才会知道)。

    对于实际上不缩减集合数量而是缩小数字的情况,无论如何,缩小可能是有问题的,所以您应该适当地修正代码。