从'xxxx'转换为'yyyy',可能会丢失数据,抑制?

时间:2009-04-04 12:59:43

标签: c++ types suppress-warnings

有时我会收到从较长类型转换为较小类型的警告,例如:

void f( unsigned short i ) // f - accept any numeric type
                           // smaller than std::vector<>::size_type
{}

std::vector < some_type > v;
..
f ( v.size() );

通常我使用的是下一个解决方案之一:

assert( v.size() <= std::numeric_limits< unsigned short >::max() );
f( static_cast< unsigned short >( v.size() ) );

f( boost::numeric_cast<  unsigned short >( v.size() ) );

但是在我目前的工作中,没有使用过,并且从上个月开始断言是不允许的。

您知道哪些其他安全方法可以抑制此警告? 有没有陷入困境的陷阱?

PS: 并不总是可以改变f的签名,有时也应该接受小数字类型。

编辑: 我想让转换尽可能安全。

4 个答案:

答案 0 :(得分:7)

为什么要先投入?向量的大小通常是无符号整数。如果可能的话,我会说更新功能签名。 警告并不意味着被压制,而是被解决。

答案 1 :(得分:3)

解决此问题的唯一安全方法是确保在运行时不会丢失转换。断言代码仅在调试版本期间有效,并允许零售版本中的转换损失。转换损失很糟糕,因为它将传递一个完全不正确的向量大小。

您真正需要的是一种防止您创建数据丢失的机制。我推荐使用像SafeInt这样的类。这将通过抛出异常来防止溢出或下溢的转换。

SafeInt<size_t> size = v.size();
f((unsigned short)size);  // Throws if size can't fit in an unsigned short

SafeInt:http://www.codeplex.com/SafeInt

答案 2 :(得分:2)

我现在将重复我的咒语再次:如果您的代码包含强制转换,则代码或设计可能出现问题,您应该检查两者以便删除强制转换。

顺便说一句,你最后一次发布它时,你就投了赞成票!

答案 3 :(得分:2)

由于size()通常返回无符号整数,因此将其类型化为签名整数应该是非常安全的。

f(static_cast<expected-type>(v.size()));

否则,如果可能,请更改功能签名。