https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108859

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2023-02-20 00:00:00         |2025-5-29

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
#include <filesystem>
#include <iostream>
#include <stdlib.h>

int main()
{
    system("mkdir -p foo bar");
    system("touch foo/file bar/file");
    try {
        std::filesystem::copy(std::filesystem::path("foo"),
                              std::filesystem::path("bar"),
                              std::filesystem::copy_options::recursive);
    } catch (const std::filesystem::filesystem_error& e) {
        std::cerr << e.what() << '\n';
    }
}

This prints:
filesystem error: cannot copy: File exists [foo] [bar]

But the problem is that bar/file exists, not that bar exists.


This is because the throwing form of std::filesystem::copy just calls the
non-throwing form:

void
fs::copy(const path& from, const path& to, copy_options options)
{
  error_code ec;
  copy(from, to, options, ec);
  if (ec)
    _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot copy", from, to, ec));
}

We would need to reimplement the throwing form to do all the work, and throw at
the right places, or create a common implementation with an error context
object which either stores an error_code or throws when an error is reported.

Reply via email to