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

标签 c++ windows casting porting suppress-warnings

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

我们最终得到了很多;

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

主要是由于这样的代码: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。定义一个“安全转换”*函数并使用它

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

最佳答案

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

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

它的目的是......你得到了 sizevsize有一个类型。如果从一开始就使用了正确的类型,这就不会成为问题。

如果您稍后需要该值作为另一种类型,那么请将其转换; safe_cast<>是一个很好的替代方案,包括运行时边界检查。

选项 6。使用 auto

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

auto size = v.size();

让编译器为您完成繁重的工作。

关于c++ - 摆脱 "warning C4267 possible loss of data"的最佳策略是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36834799/

相关文章:

windows - 如何将多个 zip 解压缩到一个文件夹中,而不使用 zip 名称创建单独的文件夹?电源外壳

你还能在 CLI 中实现类似 GUI 的 MS-DOS 吗?

配置COM端口具有CRT功能

c - 为什么 linux 内核使用双重逻辑否定而不是强制转换为 bool 值?

c++ - 为了在测试中调用析构函数(用于测试),将基类静态转换为派生类有多可怕?

c++ - 什么时候使用引用的dynamic_cast?

c++ - 创建没有 "new"运算符的类的新实例

c++ - 如何将 std::bitset<N> 转换为 std::bitset<M>?

c++ - 最小化 C++ 中的分支 - 如果值不为零则递增

c++ - 将点之间的 “dynamic_cast”转换为类