I am using MinGW g++ (7.2.0) for compiling an application for Windows on Linux.
Excerpt from http://en.cppreference.com/w/cpp/experimental/fs/rename :
void rename(const path& old_p, const path& new_p);
When using native g++ (7.2.0) for Linux (ubuntu), std::experimental::filesystem::rename does what is described above. When using mingw-g++ (7.2.0), it does not overwrite (= delete + link) existing file but throws 'filesystem error: cannot rename: File exists'. This seems to conflict with what is stated above in the description of rename.
I have attached a minimal test program and a simple Makefile using both native g++ and mingw-g++ with wine for demonstrating the issue:
#include <experimental/filesystem>
#include <iostream>
namespace fs = std::experimental::filesystem;
int main(int, char **argv) {
fs::rename(fs::path(argv[1]), fs::path(argv[2]));
return 0;
}
This is what I get when running the test program on my 4.10.0-42-generic #46-Ubuntu:
ja@XXX $ make
uname -a
Linux XXX 4.10.0-42-generic #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
g++ --version
g++ (Ubuntu 7.2.0-18ubuntu2) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ld -v
GNU ld (GNU Binutils for Ubuntu) 2.29.1
touch testfile1 testfile2
g++ -static -static-libgcc -static-libstdc++ fstest.cc -o fstest -lstdc++fs
./fstest testfile1 testfile2
rm -f testfile1 testfile2
uname -a
Linux XXX 4.10.0-42-generic #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
i686-w64-mingw32-g++-posix --version
i686-w64-mingw32-g++-posix (GCC) 7.2-posix 20180107
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ld -v
GNU ld (GNU Binutils for Ubuntu) 2.29.1
touch testfile1 testfile2
i686-w64-mingw32-g++-posix -static -static-libgcc -static-libstdc++ fstest.cc -o fstest_mingw -lstdc++fs
wine ./fstest_mingw testfile1 testfile2
terminate called after throwing an instance of 'std::experimental::filesystem::v1::__cxx11::filesystem_error'
what(): filesystem error: cannot rename: File exists [testfile1] [testfile2]
abnormal program termination
Makefile:36: recipe for target 'mingw' failed
make: *** [mingw] Error 3
Thank you for this report.
First, may I point out that this project (MinGW.org) does not distribute any version of
g++later thang++-6.3.0, so you clearly aren't using a product which have provided, and thus, we should hardly be expected to support it. That said, our owng++-6.3.0distribution may well be similarly affected, so we may still benefit from follow-up.Without detailed investigation, I'm inclined to suggest referring this upstream, to the GCC
libstdc++developers/maintainers. On the (native) MS-Windows platform, thestd::experimental::filesystem::rename()method would be expected (ultimately) to map to either aMoveFile()orMoveFileEx()Windows-API call. The former simply cannot support the behaviour you expect; it will always fail, if thenew_pfile pre-exists. OTOH, the latter API can support the required behaviour, but if, and only if, theMOVEFILE_REPLACE_EXISTINGoption is specified in the flags argument for the call, (and then only if your process hasdeletepermission for the existing file). Perhaps the upstreamg++implementation doesn't satisfy these requirements; otherwise, the distributor of yourg++-7.2.0may have neglected some essential supporting infrastructure.Now I realise what I am using is MinGW-w64, not MinGW. I got confused about the two projects with almost similar names and posted my report to the wrong one. Sorry, my bad. Please feel free to close this one in case it is not relevant for you. I will recreate a similar report for the MinGW-w64 project.
GCC's own (upstream) documentation indicates that C++
filesystemsupport is a) experimental, and b) "rudimentary" (translation: "unlikely to work") on non-POSIX platforms (specifically Windows). Our GCC-6.3.0 distribution doesn't even attempt to support it, so I see no point in pursuing this any further.