
Beman Dawes wrote:
At 07:13 AM 11/15/2004, Peter Dimov wrote:
Now the behavior of the calls is as follows:
CreateFileA( "C:/foo.txt" ); // char -> wchar_t OS conversion CreateFileW( L"C:/foo.txt" ); // no OS conversion CreateFileA( "D:/foo.txt" ); // no OS conversion CreateFileW( L"D:/foo.txt" ); // wchar_t -> char OS conversion
Yes, that's my understanding too.
Right. Now this is what happens when you declare wchar_t to be "native". fs::function( "C:/foo.txt" ) converts to wchar_t, circumventing the OS conversion (you just argued that this was unacceptable). fs::function( L"C:/foo.txt" ); works as before. fs::function( "D:/foo.txt" ) converts to wchar_t, then the OS converts back (to "D:/foo.txt" if we are lucky). fs::function( L"D:/foo.txt" ) works as before.
Furthermore, consider a typical scenario where the application has its own "native" character type, app_char_t. In a design that enforces a single "native" character type boost_fs_char_t ("native" is a deceptive term due to the above scenario), there are potentially redundant (and not necessarily preserving) conversions from app_char_t to boost_fs_char_t and then from boost_fs_char_t to the filesystem character type.
Yes. Note that even if a dual scheme is used, that same situation might arise:
if ( fs::exists( "c:foo" ) ) ... if ( fs::exists( L"d:foo" ) ) ...
Notice that a narrow character path was given for the wide-character filesystem and a wide character path given for the narrow-character file system. If the type of the user supplied path is what determines the API to use, the O/S may still have to do conversions when there is a mismatch with the file system.
Of course. The point I am making is that, on a dual OS, (a) the only place where conversions happen must be the OS and (b) at most one conversion should occur.
Do you see any alternative?
There need not be an alternative. The idea is to not do worse than that.
Your strongest argument IMO is the point about conversions not necessarily being value preserving.
This is only an example of how things can go wrong. Another would be when a service pack or a new version changes the default OS conversion. If you rely on the ability to duplicate the OS behavior exactly, there'll be trouble. The bottom line is that, on a dual OS, if we get a narrow string from the user, we should ultimately pass a narrow string to the OS, and if we get a wide string, we should pass a wide string. Everything else will be wrong in some contexts.