Sv: Sv: Sv: Sv: Sv: g++ and c++17 filesystem

Ken Brown
Tue Nov 24 20:06:57 GMT 2020

On 11/24/2020 9:31 AM, Kristian Ivarsson via Cygwin wrote:
>> On 11/24/2020 4:32 AM, Kristian Ivarsson via Cygwin wrote:
>>> all the std::filesystem implementations I've seen for Windows
>> The implementation on top of Cygwin is not "for Windows", it's "for
>> Cygwin", i.e., "for Posix".  And for Cygwin that's the right thing to do.
>> And that's where we keep talking at cross purposes.
> Maybe it is the right thing to do, but what is your take of why it must be so (all the way) ?
> I also do understand that it have several advantages in the implementation of std::filesystem but it also imply an extra layer of abstraction to the underlaying platform, but to just remove the _CYGWIN_ macro when building it would make std::filesystem to not understand /cygdrive at all (and I guess that would confuse other users;-) so I guess it would require some more sophisticated implementation (or extend the number of exceptions already existing in the underlaying Cygwin-Posix-implementation)

I'd like to try to make this discussion more concrete by looking at what's 
actually going on in the test program main.cpp that you posted at the beginning 
of that thread.  (I ran it under strace and gdb to see this for myself.)

First, your program calls std::filesystem::exists, which ultimately calls 
stat(2) in the Cygwin DLL.  The work for this is done in the path_conv::check 
function and various functions that it calls.  These functions have code that 
recognizes Win32 paths like C:\Temp, and std::filesystem::exists therefore 
reports "true".  This is consistent with the statement at about how the Cygwin 
DLL treats Win32 paths.

Next, your program calls std::filesystem::canonical.  This calls 
std::filesystem::absolute, which reports that C:\Temp is not an absolute path. 
It therefore tries to treat it as a relative path and fails with "No such file 
or directory" because <current directory>/C:\Temp does not exist.  Note that the 
Cygwin DLL never sees the original path C:\Temp in this case.  Again, this is 
consistent with the statement in the documentation that Cygwin applications do 
not necessarily recognize Win32 paths.

You say this is a bug, because first you're told that C:\Temp exists and then 
you're told it doesn't.  But I think it just illustrates the hazards of using 
Win32 paths in Cygwin, which tries hard to emulate Posix.  Sometimes you can get 
away with using Win32 paths and sometimes you can't, depending on how and when 
the Cygwin DLL is involved.

I don't see a good way to avoid this inconsistency.  We could change Cygwin so 
that it rigidly recognizes only Posix paths.  Cygwin would then be consistent, 
but we would be removing a feature that many users have become accustomed to. 
And it wouldn't help you.  Or we could ask all Cygwin package maintainers to try 
to patch their packages so that they recognize Win32 paths, but that's simply 
not feasible, nor would many package maintainers be willing to invest the 
required time.

I tried it once with emacs, which I maintain, in response to a user request.  I 
failed miserably.  Every change I made broke something else, and I finally gave up.

I don't think g++ will be any easier than emacs, and I don't think you can 
expect the g++ maintainer to work on this.


More information about the Cygwin mailing list