Visual C++ 2015 error

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Robert Pope
Posts: 558
Joined: Sat Mar 25, 2006 8:27 pm

Visual C++ 2015 error

Post by Robert Pope »

I upgraded to Windows 10 this weekend, so I decided to upgrade from Visual Studio 2013 to 2015 while I was at it. To my surprise, my chess program doesn't compile anymore. The problem is some generic I/O code I borrowed from the WinBoard forum a long time ago:

Code: Select all

int Bioskey(void) { 
  static int init = 0, pipe; 
  static HANDLE inh; 
  DWORD dw; 
  if (XBoard) { 
    if (!init) { 
      init = 1; 
      inh = GetStdHandle(STD_INPUT_HANDLE); 
      pipe = !GetConsoleMode(inh, &dw); 
      if (!pipe) { 
        SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT)); 
        FlushConsoleInputBuffer(inh); 
      } 
    } 
    if (stdin->_cnt > 0) 
      return stdin->_cnt; 
    if (pipe) { 
      if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1; 
        return dw; 
    } 
    else { 
      GetNumberOfConsoleInputEvents(inh, &dw); 
      return dw <= 1 ? 0 &#58; dw; 
    &#125; 
  &#125; 
  else return _kbhit&#40;); 
&#125; 
It chokes on:
if (stdin->_cnt > 0)
return stdin->_cnt;
with Error C2039: '_cnt': is not a member of '_iobuf'
class "_iobuf" has no member "_cnt"

Any ideas? I've been googling, but can't figure out what the issue is, or how to resolve it.
jdart
Posts: 4367
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: Visual C++ 2015 error

Post by jdart »

You are referencing a non-standard variable that you are assuming is part of "stdin". It isn't there anymore in the new Windows version.

This code from Arasan shows how I handle input on Windows:

Code: Select all

 while (!polling_terminated&#41; &#123;
      BOOL bSuccess;
      DWORD dwRead;
      if (_isatty&#40;_fileno&#40;stdin&#41;)) &#123;
         // we are reading direct from the console, enable echo & control-char
         // processing
         if (!SetConsoleMode&#40;hStdin, ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT |
                         ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT&#41;) &#123;
            cerr << "SetConsoleMode failed" << endl;
         &#125;
         bSuccess = ReadConsole&#40;hStdin, buf, 1024, &dwRead, NULL&#41;;
      &#125;
      else &#123;
         bSuccess = ReadFile&#40;hStdin, buf, 1024, &dwRead, NULL&#41;;
         if (! bSuccess || dwRead == 0&#41; &#123;
            if &#40;doTrace&#41; cout << "# read error from input pipe" << endl;
#ifdef UCI_LOG
            ucilog << "read error from input pipe" << endl << &#40;flush&#41;;
#endif
            break;
	 &#125;
      &#125;
      processCmdChars&#40;buf,&#40;int&#41;dwRead&#41;;
   &#125;
Joost Buijs
Posts: 1564
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Visual C++ 2015 error

Post by Joost Buijs »

This morning I installed VS2015 under Windows 10 and I also have some issues with the IO.

My engine compiles without errors and works fine with Arena, but when I use it with WinBoard/Polyglot the IO just hangs.

Basically I do this:

Code: Select all


void uci&#58;&#58;init_io
&#123;
	hStdin = GetStdHandle&#40;STD_INPUT_HANDLE&#41;;
	hStdout = GetStdHandle&#40;STD_OUTPUT_HANDLE&#41;;
	bPipe = &#40;GetFileType&#40;hStdin&#41; == FILE_TYPE_PIPE&#41;;

	if &#40;bPipe&#41; &#123;
		setvbuf&#40;stdin, NULL, _IONBF, 0&#41;;
		setvbuf&#40;stdout, NULL, _IONBF, 0&#41;;
	&#125;

	fflush&#40;NULL&#41;;
&#125;

bool uci&#58;&#58;check_io
&#123;
	if &#40;bPipe&#41; &#123; // anonymous pipe
		DWORD dwAvail = 0;
		if &#40;PeekNamedPipe&#40;hStdin, NULL, 0, NULL, &dwAvail, NULL&#41; && dwAvail > 0&#41;
			return true;
		return false;
	&#125;

        // console
        return bool&#40;_kbhit&#40;));
&#125;

After this I just read from stdin and write to stdout.

Some time ago I already saw that this code had problems with VS2015 beta and decided to wait for the RTM because I thought it was a flaw of the beta.
The strange thing is that it still works with Arena but that it hangs with WinBoard/Polyglot.

The good thing is that for the first time it looks like the new Microsoft compiler generates somewhat faster code than the Intel compiler does.
I have to check this a little further.
Joost Buijs
Posts: 1564
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Visual C++ 2015 error

Post by Joost Buijs »

Although PeekNamedPipe() indicates that there are characters available the subsequent fgets() just blocks and does not return.

I wonder whether it is a bug in the MSVC++ 14.0 library or something else. With MSVC++ 12.0 there are no problems at all.
And there is the strange phenomenon that it does not happen under Arena.

When I have some time I will dive further into it.
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Visual C++ 2015 error

Post by mar »

Robert Pope wrote:The problem is some generic I/O code I borrowed from the WinBoard forum a long time ago
If you ran your engine in a separate thread, you could have one simple polling loop in main (or elsewhere),
no need for nonportable windows-specific magic ang ugly polling within search...
Joost Buijs
Posts: 1564
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Visual C++ 2015 error

Post by Joost Buijs »

mar wrote:
Robert Pope wrote:The problem is some generic I/O code I borrowed from the WinBoard forum a long time ago
If you ran your engine in a separate thread, you could have one simple polling loop in main (or elsewhere),
no need for nonportable windows-specific magic ang ugly polling within search...
Handling the IO in a separate thread is a lot cleaner, I agree. In the next version of my engine I will certainly do it this way.

A lot of code I use is at least 15 years old and I never changed it because it always worked.
Now I'm intrigued by the fact that it suddenly breaks in combination with MSVC++ 14.0 and WinBoard/Polyglot.
Joost Buijs
Posts: 1564
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Visual C++ 2015 error

Post by Joost Buijs »

Disabling buffering on stdio in combination with fgets() seems to be the culprit.
I don't want to spend more time on it, I will stick to MSVC 12 for the time being.
In the future when I have completely rewritten the IO part I will give it another try.
Robert Pope
Posts: 558
Joined: Sat Mar 25, 2006 8:27 pm

Re: Visual C++ 2015 error

Post by Robert Pope »

mar wrote:
Robert Pope wrote:The problem is some generic I/O code I borrowed from the WinBoard forum a long time ago
If you ran your engine in a separate thread, you could have one simple polling loop in main (or elsewhere),
no need for nonportable windows-specific magic ang ugly polling within search...
True, but then I'd have to get more competent with threads. Trades one can of worms for another. :)

What's the portable method of threading?
jdart
Posts: 4367
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: Visual C++ 2015 error

Post by jdart »

Generally threading code is not portable. Intel has a threading library that may help though (https://www.threadingbuildingblocks.org/).

C++ 11 has portable threading constructs built into the language. So do some other languages (Go for example). For older C++ there is the Boost library.

(I am using none of these: I have #ifdefs and a couple utility classes that help hide platform dependencies).

--Jon
Robert Pope
Posts: 558
Joined: Sat Mar 25, 2006 8:27 pm

Re: Visual C++ 2015 error

Post by Robert Pope »

This is driving me crazy. I compiled and ran the following code on MS Visual Studio Professional 2013 (Windows 8.1):

Code: Select all

#include<stdio.h>
int main&#40;int argc, char* argv&#91;&#93;)
&#123;
char buf&#91;256&#93;;
    setvbuf&#40;stdin, NULL, _IONBF, 0&#41;;
    printf&#40;"waiting for input\n");
    fgets&#40;buf, 80, stdin&#41;;
    printf&#40;"received %s\n", buf&#41;;
    printf&#40;"exiting&#58;\n");
    fgets&#40;buf, 80, stdin&#41;;
return 0;
&#125;
The output is as expected:

waiting for input
A
received A

exiting:
B

But if I compile the exact same code in MS Visual Studio Community 2015 (Windows 10), it keeps waiting for input until I press enter twice:

waiting for input
A
B
C
D


received ABCD


exiting:
E
F
G

If I comment out the setvbuf(), it works as expected, but then I am buffering input.