Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ STL API的差异(当我将平台从x64切换到x86时,VS2017)_C++_Visual Studio_X86_X86 64_C++17 - Fatal编程技术网

C++ STL API的差异(当我将平台从x64切换到x86时,VS2017)

C++ STL API的差异(当我将平台从x64切换到x86时,VS2017),c++,visual-studio,x86,x86-64,c++17,C++,Visual Studio,X86,X86 64,C++17,我有一个简单的ReadTextFile(完整路径)函数: 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.

我有一个简单的ReadTextFile(完整路径)函数:

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;
}
std::wstring CEngine::load_text_文件(std::wstring&full_路径)
{
std::wstring buffer=m_text_file_cache[完整路径];
if(buffer.empty())//加载文件:
{
std::wifstream wif(完整路径);
wif.seekg(0,std::ios::end);
buffer.resize(wif.tellg());//调试/发布x86时:警告C4244:“参数”:从“std::streamoff”转换为“const unsigned int”,可能会丢失数据
wif.seekg(0);
wif.read(buffer.data(),buffer.size());//在调试/发布x86时:错误C2664:'std::basic_istream&std::basic_istream::read(_Elem*,std::streamsize)':无法将参数1从'const wchar_t*'转换为'wchar_t*'
m_text_file_cache[完整路径]=缓冲区;
}
返回缓冲区;
}
  • m_text_file_cache
    只是一个std::map缓存,用于减少磁盘I/O。忽略它

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

导致警告的原因是,即使在x86模式下,文件仍然(可能)大于4GB,这意味着它们的大小类型为64位。64位整数截断为32位整数,并带有编译器提供的警告<代码>静态转换到
无符号整数
修复

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

另外,不要使用C样式转换来修复此问题,如
(wchar\u t*)buffer.data()
,因为这可能会隐藏此问题,直到它在代码的后期爆发。如果您被迫为此代码使用C++17之前的版本,请选择
const_cast

wif.read(const_cast<wchar*>(buffer.data()) , buffer.size());
wif.read(const_cast(buffer.data()),buffer.size());
(警告问题)

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


从标准的角度来看,
size\t
定义。

std::string::data
返回一个
const
指针,直到C++17。我想知道x64库的实现是否比x86库的实现早一点。您应该能够查看标题(或多个标题)中的
数据的定义,以了解发生了什么。出现警告的原因应该是显而易见的。在32位应用程序中,字符串使用32位索引和大小,但
tellg()
返回64位值,因此您将无法存储大于4GB的文件。在C++17之前,
wstring::data()
不会返回非
const
指针。您可以使用多种不同的方法,尝试其他不依赖32位/64位数据类型的方法。
tellg
有点奇怪。它所能保证的是,您可以获得一个令牌,用于返回到流中的同一点。这可能与文件的开头有关,也可能与文件的开头无关,因此您不能指望查找到结尾,然后调用
tellg
来提供文件的大小。很明显,您的目标是MSCV,seek-and-tell技巧很有效(至少现在是这样),但如果您必须将代码移植到其他地方,这可能会产生影响。@user4581301问题是我在VS IDE中无意中仅为x64而不是所有配置设置了C++17。希雷玛猜对了。我在IDE中修复了它,错误消失了。@AmitG。谢谢我是从你下面的评论中收集到的。很好,这不是我想象中的噩梦。不知道你可以在MSVC中设定标准。不要这么多地使用它,对于我这样做的情况,我仍在努力使我的公司超越MSVC 2010,在MSVC 2010中,标准合规性真的没有那么重要。与其使用
const_cast
,不如使用
operator[]
wif.read(&buffer[0],buffer.size())@RemyLebeau你可以,但我永远不会推荐它,因为它会产生混乱。这是对
const\u cast
@Xirema的一种完全有效且符合标准的使用,您是对的。我无意中在IDE中仅为x64而不是所有配置设置了C++17。现在它有意义了;错误消失了。@Xirema那会是什么乱七八糟的事<当
buffer.size()
为0时,code>operator[]
不执行边界检查,因此
buffer[0]
将表示与
buffer.end()相同的地址。
buffer.size()为0时,可以安全地引用内存缓冲区的末尾,只要不取消引用它,
read()
buffer.size()时不会
为0。此外,
操作符[]
在C++11和更高版本中保证返回一个有效地址,即使
size()
为0(在C++11之前,它将返回一个未定义的地址,但这是可以的,因为
read()
无论如何都不会访问地址)。
size\u t
用于对象的大小(在内存中)。没有理由期望它可以在支持大文件的系统上保留文件偏移量。
std::wstring :: resize (size_type n);