Bug 9776 – Make raw write mode the default

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-21T07:55:05Z
Last change time
2017-09-05T17:30:49Z
Assigned to
No Owner
Creator
Nick Sabalausky

Comments

Comment #0 by bus_dbugzilla — 2013-03-21T07:55:05Z
On Windows, the "write*" functions automatically convert \n to \r\n. This is both error-prone and completely unnecessary on all versions of windows that DMD/Phobos supports (ie, at *least* as far back as XP). On all such versions of Windows, the command line, BATch files and code editors all handle \n perfectly fine. If there are any obscure situations where \r\n is still expected, they are more properly handled as-needed as special cases. The big-prone nature of non-raw write is demonstrated in this straightforward code: -------------------------------------- import std.file; import std.stdio; void transform(string str) { /+ ...perform some modification of 'str'... +/ return str; } void main() { auto str = cast(string) read(args[1]); str = transform(str); write(str); } -------------------------------------- That simple code is *wrong*: It works correctly for all input on Unix: Output newlines match input newlines. Always. The code never asks for newlines to be messed with, and therefore they never are. But on Windows the behavior is just plain weird: Unix-style newlines in the input are silently and forcefully converted to Windows-style newlines behind the user's back. And even worse yet, *Windows*-style newlines on the input are converted to a bizarre "Mac9 plus Windows-style" combination of "\r\r\n" (not only is that wrong period, but this sequence is often interpreted as two newlines which makes it even worse). Using rawWrite fixes the problem, and creates *no* problem. People have been caught by that bug on various occasions, such as: https://github.com/repeatedly/mustache-d/issues/3 See also the discussion on this matter on the D newsgroup: http://forum.dlang.org/post/20130320103418.00005416@unknown Various people have agreed, and so far, there hasn't been anyone arguing to keep the current behavior.
Comment #1 by andrej.mitrovich — 2013-09-21T11:20:06Z
*** Issue 11087 has been marked as a duplicate of this issue. ***
Comment #2 by andrej.mitrovich — 2013-09-21T11:20:33Z
Simple test-case from Issue 11087: ----- import std.file; import std.stdio; void main() { std.file.write("test1.txt", "a\nb"); auto file2 = File("test2.txt", "w"); file2.write("a\nb"); file2.close(); auto res1 = cast(byte[])std.file.read("test1.txt"); auto res2 = cast(byte[])std.file.read("test2.txt"); writeln(res1); // writes [97, 10, 98] writeln(res2); // writes [97, 13, 10, 98] } -----
Comment #3 by bus_dbugzilla — 2015-06-16T02:02:31Z
Another way of putting it. Do this on a Windows machine: --------------------------------------- > type test.d import std.file, std.stdio; void main() { auto str = cast(string) std.file.read("input.txt"); stdout.write(str); } > echo line1 > input.txt > echo line2 >> input.txt > dmd -run test.d > output.txt --------------------------------------- Then notice that "input.txt" and "output.txt" are DIFFERENT (Check in a hex viewer or any decent editor that supports visible line endings.) The input has \r\n, but the output has \r\r\n. Some editors will actually display it like this: --------------- line1 line2 ---------------
Comment #4 by dlang-bugzilla — 2015-06-16T02:22:16Z
I seriously doubt this is going to be changed as long as we use the C I/O API. Not to mention that this would be a breaking change. (In reply to Nick Sabalausky from comment #0) > completely unnecessary on all versions of windows that > DMD/Phobos supports (ie, at *least* as far back as XP). Wrong, the Windows console still treats \n as "line feed without carriage return". (In reply to Andrej Mitrovic from comment #2) > auto file2 = File("test2.txt", "w"); Use "wb" as the file mode, this is what it's for. (In reply to Nick Sabalausky from comment #3) > auto str = cast(string) std.file.read("input.txt"); > stdout.write(str); Do not mix C I/O with OS I/O APIs.
Comment #5 by dlang-bugzilla — 2015-06-16T02:28:06Z
(In reply to Vladimir Panteleev from comment #4) > Wrong, the Windows console still treats \n as "line feed without carriage > return". I just tested and it seems I misremembered, sorry. But it's still a breaking change.
Comment #6 by bus_dbugzilla — 2015-06-16T15:58:25Z
(In reply to Vladimir Panteleev from comment #4) > (In reply to Nick Sabalausky from comment #3) > > auto str = cast(string) std.file.read("input.txt"); > > stdout.write(str); > > Do not mix C I/O with OS I/O APIs. It's not at all clear that std.file and std.stdio use completely different APIs internally. To the avrage D user, it's all just Phobos API. (In reply to Vladimir Panteleev from comment #5) > > But it's still a breaking change. So are most bugfixes.
Comment #7 by dlang-bugzilla — 2015-06-17T00:22:45Z
I'm telling you, this is not going to be fixed without introducing a new API. Edit-warring the status is not going to help.
Comment #8 by dlang-bugzilla — 2017-07-07T17:47:25Z
Whether you agree or disagree, everything here works "as designed", i.e. "do what C does". As explained, changing the default behaviour of File.open would be a breaking change and is not going to happen.
Comment #9 by bugzilla — 2017-07-08T19:45:44Z
> unnecessary on all versions of windows Windows Notepad fails with it. It's similar to the \ path separator problem on Windows. Many programs, including lots of Microsoft programs, fail to deal with / properly.
Comment #10 by bus_dbugzilla — 2017-07-09T00:46:27Z
As already said before, windows notepad is the *only program that doesn't handle it (which makes it very *unlike* '/' if indeed "many programs" fail to deal with properly - which is an exaggeration anyway, but that's beside the point). If I'm wrong and \n is indeed poorly supported on Windows, then it should be a simple matter to go ahead and name other examples. Contrast that to the "\r\r\n" that D code is demonstrably prone to emitting on Windows, which is handled correctly by little, if anything, on any OS. The safer behavior is clear, and the consensus of the discussion was the same. Stubborn clingage to false information and misplaced fears is not befitting of D.
Comment #11 by dfj1esp02 — 2017-09-05T13:34:33Z
*** Issue 4555 has been marked as a duplicate of this issue. ***
Comment #12 by dfj1esp02 — 2017-09-05T13:35:33Z
(In reply to Vladimir Panteleev from comment #8) > Whether you agree or disagree, everything here works "as designed" Not documented though.
Comment #13 by dlang-bugzilla — 2017-09-05T15:09:51Z
(In reply to anonymous4 from comment #12) > Not documented though. How so? The documentation for stdioOpenmode says "range or string represting the open mode (with the same semantics as in the C standard library fopen function)", so the defaults for unspecified options are left to the C standard library implementation. AIUI, it's not part of the language because on POSIX binary and text modes behave the same.
Comment #14 by dfj1esp02 — 2017-09-05T17:30:49Z
Not documented that std.file doesn't use C stdio and is not compatible with it (and not intended) and no remark to not mix it with stdio as was suggested here.