This problem happens on Windows 8.1. When I wrote stdout.write("ああn") in 
test.nim and compiled with nim c -r test.nim, it prints ああ on console 
correctly. But when I compile it with nim cpp -r test.nim, it doesn't print 
correctly. Same problem happens with echo proc. (echo use write proc internally 
and reading write proc code is easier than reading echo proc code.) 

# Background

I use cmd.exe from Neovim's terminal buffer and use neovim with neovim-qt on 
windows. Code page must be set to 65001 because Nim supports only utf8. On my 
pc, cmd.exe uses code page 932 in default and command line programs (except 
programs written with Nim) can output japanese text and I can type japanese 
with IME. (IME is a program to type japanese on GUI or console program) When I 
run chcp 65001 or nim command line program and code page is set to 65001 on 
cmd.exe, any programs cannot print japanese correctly and I cannot type 
japanese because I cannot enable IME. (Can you print and type CJK characters on 
windows console on windows10 after chcp 65001?) When I use cmd.exe on Neovim's 
terminal buffer, Nim programs that is compiled with nim c can print japanese 
correctly and I can enable IME and type japanese. (Reading japanese from stdin 
needs this PR: 
[https://github.com/nim-lang/Nim/pull/14782](https://github.com/nim-lang/Nim/pull/14782))

Nim supports only cmd.exe and doesn't support msys or other terminals. 
[source](https://github.com/nim-lang/Nim/issues/12556#issuecomment-547877354)

That is why I need Neovim to run Nim console programs on windows. (You might 
say Nim doesn't support cmd.exe running on Neovim's terminal buffer. But at 
least, executable file compiled with nim c and nim cpp should output same text, 
isn't it?)

# What I tried to find the bug

I added \--gc:none --stacktrace:off option to show that gc and stacktrace code 
are not related to this problem and make Nim generated C and C++ code are easy 
to read. 
    
    
    f:\temp>nim -v
    Nim Compiler Version 1.3.5 [Windows: amd64]
    Compiled at 2020-07-23
    Copyright (c) 2006-2020 by Andreas Rumpf
    
    git hash: 14d16c2174a4fcefd405f8c4eeaf57a6dcd2731d
    active boot switches: -d:release
    
    f:\temp>type test.nim
    stdout.write("ああ\n")
    
    f:\temp>nim c --gc:none --stacktrace:off -f test.nim
    ....
    
    f:\temp>test.exe
    ああ
    
    f:\temp>test.exe > test.exe_c_out
    
    f:\temp>nim cpp --gc:none --stacktrace:off -f test.nim
    ....
    
    f:\temp>test.exe
    ������
    
    f:\temp>test.exe > test.exe_cpp_out
    
    f:\temp>type test.exe_c_out
    ああ
    
    f:\temp>type test.exe_cpp_out
    ああ
    
    f:\temp>sha1sum test.exe_c_out
    8614b3443740adba28825665bca067e454d1f42c  test.exe_c_out
    
    f:\temp>sha1sum test.exe_cpp_out
    8614b3443740adba28825665bca067e454d1f42c  test.exe_cpp_out
    
    f:\temp>
    
    
    Run

test.exe compiled with nim cpp doesn't print ああ correctly. But when their 
stdout was redirected to the file, the content of the file is same! I think 
this means both executables call fprintf with same parameters. (fprintf is a C 
standard library function that is used to implement write proc on windows)

I read generated C code and this is C code that call same C functions. Nim 
convert string literal "ああ" in Nim code to `"\343\201\202\343\201\202"` and put 
it in C code. I also read generated C++ code and it seems they call same C 
functions. 
    
    
    #include <stdio.h>
    #include <io.h>
    #include <fcntl.h>
    #include <Windows.h>
    
    int main() {
      _setmode(_fileno(stdin), _O_BINARY);
      _setmode(_fileno(stdout), _O_BINARY);
      _setmode(_fileno(stderr), _O_BINARY);
      SetConsoleOutputCP(65001);
      SetConsoleCP(65001);
            fprintf(stdout, "%s", "\343\201\202\343\201\202\n");
      
      return 0;
    }
    
    
    Run

I compiled this C code with same gcc and parameters used by nim c, but this 
code doesn't print first "あ" correctly. 
    
    
    f:\temp>chcp 65001
    Active code page: 65001
    
    f:\temp>gcc.exe -w -fmax-errors=3 -mno-ms-bitfields -o testfc.exe testf.c
    
    f:\temp>testfc.exe
    ���あ
    
    f:\temp>
    
    
    Run

Nim code compiled with nim c call other C functions that affect how fprintf 
write stdout? (Nim code calls signal C function in stdlib_system.nim.c but I 
don't think it is related to this problem)

I tried vcc backend. Both nim c and nim cpp correctly print "ああ". So, this 
problem can be a bug in g++? 
    
    
    f:\temp>nim cpp --gc:none --stacktrace:off -f --cc:vcc test.nim
    ....
    f:\temp>test.exe
    ああ
    
    f:\temp>nim c --gc:none --stacktrace:off -f --cc:vcc test.nim
    ....
    
    f:\temp>test.exe
    ああ
    
    f:\temp>
    
    
    Run

I use gcc version 9.3.0 that is installed with [scoop](https://scoop.sh/) 
package manager, because it is newer than [gcc distributed 
here](https://nim-lang.org/install_windows.html) and updating it with scoop is 
easy. I downloaded MingW from 
[https://nim-lang.org/download/mingw64.7z](https://nim-lang.org/download/mingw64.7z)
 and tested my code, but results were same.

Thank you for reading this long post. Any help would be appreciated.

Reply via email to