'uintmax_t' 'size_t'和'unsigned int'转换,数据丢失是什么?

What is the loss of data in 'uintmax_t' to 'size_t' and 'unsigned int' conversion?

本文关键字:数据 是什么 unsigned uintmax size int 转换      更新时间:2023-10-16

我明白了:

警告C4244: '初始化':转换从'uintmax_t'到'unsigned int',可能丢失数据

:

boost::shared_array<char> buffer( new char[file->size]);

…,然后是这个:

警告C4244: 'argument':从'uintmax_t'转换为'size_t',可能丢失数据

:

boost::asio::write(*socket, boost::asio::buffer(buffer.get(), file->size));

我该害怕还是没事?

可能file->size的类型是uintmax_t,它比operator new[]的类型size_t大。通常第一个可以是64位整数,而第二个只能是32位整数。

实际上,当您试图处理超过4GB的文件时,这将导致问题,因为size_t不能表示如此大的字节数。如果您只希望处理size_t大到足以存储文件大小的较小文件,则不会出现问题。

这取决于实现。

uintmax_t是该实现提供的最大的unsigned类型。size_tsizeof运算符的结果类型,大到足以容纳任何对象的大小。当然,unsigned intint类型的无符号版本。

唯一的保证是size_tunsigned int都至少是16位(但可能更大),uintmax_t至少是64位(假设C99规则),uintmax_t至少与任何其他无符号类型一样宽。

假设file->size是以字节为单位的文件大小,并且它的类型可能是uintmax_t。根据系统的不同,文件的最大大小可能比内存中任何可能对象的大小都要大。

如果这个特定文件的大小不是太大,就没有问题。但是,如果size_t是32位(意味着对象不能大于4gb),而您的文件是5gb,那么您将无法分配一个足够大的内存缓冲区来容纳文件的内容。

size_t的最大值SIZE_MAX只是对象最大大小的上界。仅仅因为SIZE_MAX是2**31-1,这并不一定意味着你可以创建一个那么大的对象。

这取决于你的文件有多大。

大多数计算机具有比RAM更大的磁盘存储空间,并且在许多情况下可以支持一个大到RAM无法容纳的单个文件。在这种情况下,分配可能会失败,或者文件大小可能被截断为指针大小,在这种情况下,您将分配一个不足以容纳文件的缓冲区。

您可以使用:

来检测过大的文件。
size_t buffersize(file->size);
if (buffersize != file->size) { /* error, file too large to fit into virtual memory */ }
/* use buffersize for buffer allocation */