现代C++中STL API的差异(当我在VS2017中将目标从x64切换到x86时)

Differences in STL API in Modern C++ (When I switch target, from x64 to x86, in VS2017)

本文关键字:x64 目标 x86 VS2017 API STL C++ 现代      更新时间:2023-10-16

(当我将平台从x64切换到x86时,VS2017)

我有这个简单的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。

之所以出现警告,是因为即使您处于 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(),因为这可能会隐藏此问题,直到它在代码的后面部分爆炸。如果您被迫为此代码使用 pre-C++17,请首选const_cast

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

(警告问题)

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

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

从标准的角度来看,这里讨论的定义size_t