我已将我的VC ++项目表单VS2008迁移到VS2013并收到一些警告:
C4244: '+=' : conversion from 'std::streamsize' to 'size_t', possible loss of data.
如何解决这些类型的警告?
答案 0 :(得分:1)
正如c++ reference中所述,std::streamsize
被定义为signed
(强调我的):
类型
std::streamsize
是一个带符号的整数类型,用于表示在I / O操作中传输的字符数或I / O缓冲区的大小。它用作std::size_t
的签名对应项,类似于POSIX类型ssize_t
。
无论如何,似乎没有具体说明。
通常,从signed
到unsigned
类型的转换具有相同的基数(例如long
)不应发出有关可能的数据丢失的警告(除非使用符号指示符是意)。
它可能是Visual Studio C ++中糟糕的实现。
答案 1 :(得分:1)
在MSVC 2013中std::streamsize
是:
typedef _Longlong streamsize;
typedef _LONGLONG _Longlong;
#define _LONGLONG __int64
size_t
是:
typedef unsigned __int64 size_t;
因此,一个简单的责备案例是:
unsigned __int64 b = 1;
__int64 a = b;
然而,这不会发出警告 - 所以你可能在某处将size_t
重新定义为32位?
为清楚起见:
std::streamsize b = 1;
size_t a = 0;
b = a;
也没有发出警告。
答案 2 :(得分:0)
这取决于用途。根据{{3}},
除了std :: strstreambuf的构造函数外,从不使用std :: streamsize的负值。
因此,您可以放心地使用已签名的值。
std::streamsize i;
// ...
size_t u = static_cast<size_t>(i);
但是,在更一般的情况下(与πάνταῥεῖ写的相反),我认为警告是有效的(即使gcc
不会吐出类似的警告)。比较有符号和无符号值时,最好明确您的意思。
您可以强制取消签名,例如使用如下代码段(感谢cppreference.com的一般形式):
#include <iostream>
template <typename T>
typename std::enable_if< std::is_signed<T>::value, typename std::make_unsigned<T>::type >::type
force_unsigned(T u) {
if (u < 0) {
throw std::overflow_error("Cannot use negative value as unsigned type");
}
return static_cast< typename std::make_unsigned<T>::type >(u);
}
template <typename T>
typename std::enable_if< !std::is_signed<T>::value, T >::type
force_unsigned(T u) {
return u;
}
int main() {
std::cout << force_unsigned((unsigned int)1) << std::endl;
std::cout << force_unsigned((int)1) << std::endl;
std::cout << force_unsigned((int)0) << std::endl;
std::cout << force_unsigned((int)-1) << std::endl;
return 0;
}