Created attachment 50280 [details] test case Compiling with gcc 10.2.0 from the mxe cross compilation environment for Windows. The attached sample program says it all. It shows that std::filesystem::("\\server\share\file.txt").is_absolute() is false and turns std::filesystem::absolute("\\server\share\file.txt") into something like "C:\server\share\file.txt". boost::filesystem::path(…).is_aboslute(), on the other hand, considers UNC paths absolute & leaves them unmodified via boost::filesystem::absolute(…) The test program outputs the following: std::filesystem: original \\disky\mosu\existing_file.txt is_absolute 0 absolute "C:\\disky\\mosu\\existing_file.txt" boost::filesystem: original \\disky\mosu\existing_file.txt is_absolute 1 absolute "\\disky\mosu\existing_file.txt" Compile with something like: x86_64-w64-mingw32.static-g++ -std=c++17 \ -I/home/mosu/prog/video/mingw/cross/usr/x86_64-w64-mingw32.static/include \ -L/home/mosu/prog/video/mingw/cross/usr/x86_64-w64-mingw32.static/lib \ -o std_filesystem_unc_paths_vs_absolute.exe \ std_filesystem_unc_paths_vs_absolute.cpp \ -lboost_filesystem-mt-s-x64 -lboost_system-mt-s-x64
The problem is not path::is_absolute(), it's path::has_root_name(), which (by design) only handles //rootname on Cygwin: #ifdef __CYGWIN__ // Interpret "//x" as a root-name, not root-dir + filename # define SLASHSLASH_IS_ROOTNAME 1 #endif I don't have boost built for mingw. Does boost recognise "//disky/mosu" as a valid path, or does a UNC root-name have to use backslashes? i.e. is path("//disky/mosu").has_root_name() true?
The following code tests forward & backward slashes with both std::filesystem (gcc 10.2.0, mingw via MXE) and boost::filesystem (Boost 1.74.0): auto slashes = R"(//server/share/file.txt)"s; auto backslashes = R"(\\server\share\file.txt)"s; std::cout << "std::filesystem::path(" << slashes << ").has_root_name() " << std::filesystem::path{slashes}.has_root_name() << "\n" << "std::filesystem::path(" << backslashes << ").has_root_name() " << std::filesystem::path{backslashes}.has_root_name() << "\n" << "boost::filesystem::path(" << slashes << ").has_root_name() " << boost::filesystem::path{slashes}.has_root_name() << "\n" << "boost::filesystem::path(" << backslashes << ").has_root_name() " << boost::filesystem::path{backslashes}.has_root_name() << "\n"; The output of that snippet is: std::filesystem::path(//server/share/file.txt).has_root_name() 0 std::filesystem::path(\\server\share\file.txt).has_root_name() 0 boost::filesystem::path(//server/share/file.txt).has_root_name() 1 boost::filesystem::path(\\server\share\file.txt).has_root_name() 1 Or to put it differently, std::filesystem doesn't seem to care either way while Boost recognizes both. Note that __CYGWIN__ is not defined with the compiler from MXE! I'm not compiling on Windows. This is a cross-compiler, from Linux to Windows. What is defined are things such as: [0 mosu@sweet-chili ~] x86_64-w64-mingw32.static-g++ -dM -E -x c++ - < /dev/null | sort | grep -E 'WINNT|WIN(32|64)|MINGW' #define __MINGW32__ 1 #define __MINGW64__ 1 #define __WIN32 1 #define __WIN32__ 1 #define _WIN32 1 #define WIN32 1 #define __WIN64 1 #define __WIN64__ 1 #define _WIN64 1 #define WIN64 1 #define __WINNT 1 #define __WINNT__ 1 #define WINNT 1
(In reply to Moritz Bunkus from comment #2) > while Boost recognizes both. That's what I wanted to know, thanks. > Note that __CYGWIN__ is not defined with the compiler from MXE! Obviously, because it's not cygwin. Which is why //x paths are not treated as a root-name. As I said, that's by design, but can be changed.
Oh right, sorry — I misread your earlier comment.
GCC 12.1 is being released, retargeting bugs to GCC 12.2.