Compiler Explorer中MSVC因Windows换行符与拆分视图组合出现异常错误求助
MSVC编译Range-v3跨平台换行分割代码时的权限错误问题
以下是一段用Range-v3库实现的跨平台换行分割代码,可将输入std::string按\n或\r\n分割为std::vector<std::string>:
#include <cassert> #include <iostream> #include <range/v3/algorithm/for_each.hpp> #include <range/v3/range/conversion.hpp> #include <range/v3/view/split.hpp> #include <range/v3/view/transform.hpp> #include <range/v3/view/join.hpp> #include <string> #include <vector> using namespace ranges; using namespace ranges::views; using namespace std::literals; std::vector<std::string> splitOSAgnostic(const std::string& str) { std::vector<std::string> result; for_each( str | split("\r\n"s) | transform(split("\n"s)) | join, [&result](auto snippet_view) { auto documentSnippet = snippet_view | to<std::string>; result.push_back(documentSnippet); }); return result; } int main() { auto res = splitOSAgnostic("a = 1;\nb = 2;\r\nc = 3;\n"s); assert(res[0] == "a = 1;"s); // 移除该行后MSVC编译恢复正常 assert(res[1] == "b = 2;"s); assert(res[2] == "c = 3;"s); }
在在线编译环境中使用MSVC编译时,出现如下错误:
example.cpp <source> : fatal error C1083: Cannot open compiler generated file: 'C:\Users\ContainerAdministrator\AppData\Local\Temp\compiler-explorer-compiler2023110-17256-1pb5efl.2aus\output.s.obj': Permission denied Compiler returned: 1
该代码在Clang和GCC下可正常编译,仅移除第一个assert语句后MSVC编译也恢复正常。
错误原因分析
这是MSVC在在线容器环境下处理复杂模板实例化时的特定bug,具体原因如下:
- Range-v3的链式视图(
split+transform+split+join)会生成极度复杂的嵌套模板类型,当配合第一个assert中的字符串比较操作时,MSVC需要实例化大量额外的模板代码,导致临时文件的生成、写入流程出现异常,触发文件权限冲突。 - 移除第一个
assert后,模板实例化的复杂度大幅降低,编译器不需要生成过多临时代码,因此避开了这个权限问题。 - Clang和GCC的模板处理机制更高效,不会在该环境下触发这类临时文件管理异常;换本地MSVC环境编译该代码,大概率也不会出现此问题。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

