Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does path's iterator return "\\" while traversing?

Tags:

c++

c++17

I am using a new and modern C++17 with the filesystem API. I am working in Windows, with Visual Studio 2017.

The following code gives an unexpected result:

#include <iostream>
#include <filesystem>

int main()
{
  std::filesystem::path path(R"(D:\dir\file.cpp)");
  for (auto& dir : path)
  {
    std::cout<<dir<<std::endl;
  }
}

Result is:

"D:"
"\\"
"dir"
"file.cpp"

Why was "\\" printed?

Testing this in GCC 9.1.0 (please change '\' to '/' in the path variable), the result is:

"D:"
"dir"
"file.cpp"

Why is the behavior different?

Which result is correct according to the C++17 standard?

like image 760
PavelDev Avatar asked Jul 05 '19 11:07

PavelDev


1 Answers

See https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#fully-qualified-vs-relative-paths for some information on windows path names.

The C++ standard has this to say about path iterators ([fs.path.itr]/4):

For the elements of the pathname in the generic format, the forward traversal order is as follows:

  • The root-name element, if present.
  • The root-directory element, if present. [ Note: The generic format is required to ensure lexicographical comparison works correctly. — end note]
  • Each successive filename element, if present.
  • An empty element, if a trailing non-root directory-separator is present.

On windows, the path D:\dir\file.cpp has a disk designator of D:, followed by the root directory on that disk, \, then the path of dir, file.cpp. According to windows, D: is a root-name, so \ is a root-directory. You could have D:dir\file.cpp, but note that this is now a relative path.

On gcc, if not on windows, D: will be treated as a regular directory name (The same as ./D:/dir/file.cpp). So, there is no root-name or root-directory. If you had instead had /D:/dir/file.cpp, the iterator would have contained /, D:, dir, file.cpp.

like image 113
Artyer Avatar answered Oct 15 '22 22:10

Artyer