8

I found this page, describing the changes between c++14 and c++17:

https://isocpp.org/files/papers/p0636r0.html

... It links to this page, which describes the proposed filesystem changes:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0218r0.html

I skimmed through it. There are small wording changes to the standard, but the only code change I saw were namespace changes that removed the "experimental" and "v1" parts, so "std::experimental::filesystem::v1" became "std::filesystem", which is expected.

From what I can tell, nothing other than the namespace path changed. Does anyone know if anything else changed?

In other words, I'm using gcc with -std=c++14. Can I write code now with std::experimental::filesystem and comfortably switch to -std=c++17 in the future with only this namespace change?

Closest questions I can find to being duplicates:

How similar are Boost filesystem and the standard C++ filesystem libraries?

Are the experimental features of modern C++ reliable for long-term projects?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
user79878
  • 775
  • 9
  • 13
  • One way to find out: Use it! – tadman Jan 19 '18 at 18:49
  • 2
    I think, your best hope for proper answer is to ask this question directly on GCC website. You really need a deep knowledge of libstdc++ internal implementation to answer this question, and you won't find that many people with that outside of the group of it's developers. – SergeyA Jan 19 '18 at 19:15
  • The paper you skimmed was almost entirely *importing* Boost.Filesystem, so the question about Boost has almost the same answer as this one. – Davis Herring Jun 09 '20 at 04:49

2 Answers2

13

The major papers making changes to the filesystem library are

  • P0219R1, adding relative paths support
  • P0317R1, adding caching to directory_entry
  • P0492R2, a lengthy list of fixes and changes in response to national body comments
  • P0430R2, support for certain non-POSIX systems

There are also some relatively minor fixes and changes that can be found in the LWG issue list. Look for issues with "C++17" status. Note that some of these changes are then superseded by the papers listed above.


For existing Filesystem TS code, I expect that P0492R2 is the one that matters the most, since the remaining papers are mostly feature additions rather than changes. P0492R2 includes both technical clarifications and significant semantic changes. Some in the latter category that immediately come to mind are:

  • path(".profile").stem() is now ".profile"
  • operator/ on path had its semantics changed significantly if the rhs is an absolute path or has a root-name. path("/foo") / "/bar" is now "/bar" rather than "/foo/bar"; path("C:\\x") / "D:y" on Windows is now "D:y".
  • The old absolute is gone. system_complete has been renamed absolute.
  • permissions's signature got a minor change.
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 1
    `operator/` semantics is dangerous. If `"/bar"` comes from user input, a user could overwrite any file in the system that user of the process owns. – balki Jan 20 '18 at 00:28
  • 5
    @balki That makes no sense whatsoever. Even with the old semantics, the user can already prepend as many `../` as they want to achieve the same end. – T.C. Jan 20 '18 at 00:39
  • It is really confusing why `append(p)` will replace the original path if p is an absolute path, see https://stackoverflow.com/questions/55214156/ – Mine Mar 18 '19 at 05:19
3

A delayed reply, but I came across this question when I was myself looking for the answer to the same question. When I finally figured things out, I thought I'd post my observations here.

When migrating from std::experimental::filesystem to std::filesystem, I came across the following changes:

# c++14 std::experimental::filesystem c++17 std::filesystem
1 canonical() has an overload which accepts a base path, which could be used to resolve the path passed in the first argument canonical() doesn't have this overload, and that broke some of my code
2 canonical() doesn't check for the existence of the path canonical() does check for the existence of the path, so if you have situations where the path may not exist at the time of calling this function, switch to std::filesystem::weakly_canonical
3 The insertion operator (<<) gives you the string as it is, unquoted and unescaped. E.g. C:\my\file.txt The insertion operator (<<) adds quotes around the full path and escapes the backslashes (\). E.g. "C:\\my\\file.txt" This broke some of my tests and I had to call the string (or the wstring) methods of the path object to get the unquoted and unescaped string.
4 file_time_type is a typedef of std::chrono::system_clock::time_point file_time_type is an alias of std::chrono::time_point<filesystem::_File_time_clock>. This caused compilation errors at some places in my code where I was expecting it to be a system_clock::time_point.
Venkatesh MC
  • 111
  • 1
  • 3