从 __int64 到 size_t 的安全转换

mac*_*e_1 5 c c++ windows warnings type-conversion

我正在使用 Visual Studio 2017 在 Windows 操作系统上工作,并且我获得了以下函数来从 SO 的答案之一确定文件的大小:

__int64 FileSize(const char *filename)
{
    HANDLE hFile = CreateFile(filename, GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        return -1; // error condition, could call GetLastError to find out more
    }

    LARGE_INTEGER size;
    if (!GetFileSizeEx(hFile, &size)) {
        CloseHandle(hFile);
        return -1; // error condition, could call GetLastError to find out more
    }

    CloseHandle(hFile);
    return size.QuadPart;
}
Run Code Online (Sandbox Code Playgroud)

因此,我使用它来确定文件大小,以便使用malloc(). 由于函数malloc()接受一个size_t类型,我将FileSize()函数的返回值赋给了一个 size_t 变量,但是我收到了以下警告:

main.cpp(67):警告 C4244:“正在初始化”:从“__int64”到“::size_t”的转换,可能会丢失数据

在这种情况下,我如何安全地将文件的大小存储在size_t变量中?我知道我可以将返回值转换为size_t并消除警告,但它是否安全/正确?

Lun*_*din 4

这是非常特定于系统的。在某些系统上,size_t可能小于int64_t,这会发出警告。但当然,你不能分配比 asize_t内容纳的更多的内容。

这样做很可能是安全的size_t s = (size_t)some_int64;

但是,如果您感到偏执,您可以添加检查/断言:

#include <stdint.h>
...
if(some_int64 > SIZE_MAX) // this line is fully portable
{
  halt_and_catch_fire();
}
Run Code Online (Sandbox Code Playgroud)

SIZE_MAX是一个常量,表示变量可以容纳的最大值size_t