STL API的差异(当我将Platform从x64切换到x86时,VS2017)

时间:2018-07-11 20:42:04

标签: c++ visual-studio x86 x86-64 c++17

我有这个简单的ReadTextFile(full_path)函数:

std::wstring CEngine::load_text_file(std::wstring &full_path)
{
    std::wstring buffer = m_text_file_cache[full_path];

    if (buffer.empty()) // Load file:
    {
        std::wifstream wif(full_path);

        wif.seekg(0, std::ios::end);
        buffer.resize(wif.tellg()); // On Debug/Release x86: Warning C4244: 'argument': conversion from 'std::streamoff' to 'const unsigned int', possible loss of data
        wif.seekg(0);
        wif.read(buffer.data() , buffer.size()); // On Debug/Release x86: Error C2664: 'std::basic_istream<wchar_t,std::char_traits<wchar_t>> &std::basic_istream<wchar_t,std::char_traits<wchar_t>>::read(_Elem *,std::streamsize)': cannot convert argument 1 from 'const wchar_t *' to 'wchar_t *'

        m_text_file_cache[full_path] = buffer;
    }

    return buffer;
}
  • m_text_file_cache只是一个std :: map缓存,用于减少磁盘I / O。忽略它。

当我编译到x64(主轨道)时没有问题,但是当我编译到x86(出于好奇)时,我在代码中用注释标记了2个问题:警告C4244和错误C2664。

2 个答案:

答案 0 :(得分:3)

之所以引起该警告,是因为即使您处于x86模式,文件仍被认为(可能)大于4GB,这意味着它们的大小类型为64位。 64位整数会通过编译器提供的警告截断为32位整数。 static_castunsigned int进行修复。

由于您的x86配置可能未在C ++ 17模式下编译而导致错误,因此,data()函数返回了wchar_t const*,而不是C ++ 17的行为返回wchar_t *。更改您的编译器标志以在C ++ 17模式下进行编译,您将不再需要强制转换。最好将标志设置为“所有”配置,这样以后就不必手动更改两者。

此外,请勿使用C样式强制转换来解决此问题,例如(wchar_t*)buffer.data(),因为这可能会隐藏此问题,直到它在代码的后半部分爆炸为止。如果您被迫为此代码使用C ++ 17之前的版本,请首选const_cast

wif.read(const_cast<wchar*>(buffer.data()) , buffer.size());

答案 1 :(得分:0)

(警告问题)

x86上的警告似乎是由于x86与x64上size_t的定义不同:“ size_t(无符号__int64或无符号整数,取决于目标平台)” -MSDN“ size_t是64位Windows操作系统上的64位值” -MSDN。然后MSVC确定tellg()的返回类型为std::streamoff(通常是long long的typedef)。

std::wstring :: resize (size_type n);

从标准的角度来看,size_t的定义为discussed here