building glaurung2.1 from empty code project

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Richard Allbert
Posts: 792
Joined: Wed Jul 19, 2006 9:58 am

Re: building glaurung2.1 from empty code project

Post by Richard Allbert »

after about 60s searching, you'll find the microsoft site tells you to use setvbuf() instead.

Richard
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: building glaurung2.1 from empty code project

Post by bob »

Richard Allbert wrote:after about 60s searching, you'll find the microsoft site tells you to use setvbuf() instead.

Richard
This is all another idea based on YAPPP. (Yet Another Poor Programming Practice). The issue is buffering. Normal I/O is much more efficient when using buffering so that data accumulation can proceed independently of computation using older data. Xboard/Winboard introduced a new way for programmers to screw up, because they want to ask the question "is there input available in the buffer that I should read?" If so, they then read it, if not, they continue searching/pondering. If you use normal I/O facilities like scanf, fgets and such, there are three places where data can exist. One is in system (kernel) buffers, two is in C library buffers where scanf/etc know to look first; and the last is in the program itself if you read more than you can use at one time. Unfortunately, the usual system tests (keypressed, select(), whatever you use) are only aware of data in the system (kernel) buffer, not stuff already read by the library code or the user. So you can turn off buffering so that the C library (and your program) transfer data directly from the kernel buffer to yours, and when you test for input being present, you are testing the kernel buffer and all works well.

Or, you can do as I did, and just use non-buffered I/O system calls (read/write work on files, on network sockets and on keyboard/console just fine.) This is far safer since you are no longer manipulating underlying operating system / library operation, which might become incompatible with future releases.

There are side-effects that only get caught when a programmer tries to do something like execute another program from within his (fork/exec) or by using someone else's code to do something simple, only to find it is broken because they use a different type of I/O and the two approaches are incompatible.

anybody can use read/write without breaking anything.
CThinker
Posts: 388
Joined: Wed Mar 08, 2006 10:08 pm

Re: building glaurung2.1 from empty code project

Post by CThinker »

It is not about the API being old or being from C. Note that even the replacement being suggested is classic C.

The issue here is security. Functions from the C library that have no buffer checking should be avoided, because an attacker could supply you with an input and when you process it, you overrun your buffers.

The classic example is strcpy(). This function does not know what the destination size is. So, even if the source is larger than the destination, it would happily copy everything over.

The preferred alternative is strncpy(), which allows you to tell the function what is the size of the destination buffer so it would not copy more than that.

MS now has created alternatives to classic standard C functions, and most of them just have a buffer size as an additional parameter. The names are just like the current ones, but with the prefix "s_" (e.g., sprintf -> s_sprintf).
Tord Romstad
Posts: 1808
Joined: Wed Mar 08, 2006 9:19 pm
Location: Oslo, Norway

Re: building glaurung2.1 from empty code project

Post by Tord Romstad »

It is strange to yet again find myself defending C++, which is one of the most ugly and unpleasant of the many programming languages I have ever worked with.
Zach Wegner wrote:Some people prefer C. I think it looks a lot nicer, and it's easier to code in.
Looks nicer, yes. Easier to code in? How? Almost everything you do in C you can do in exactly the same way in C++. The only difference I can think of is that you need more typecasts in C++, but in my opinion that is mostly a good thing: If I find that I need to clutter my code with lots of typecasts, it is usually a good sign that I am doing something stuipd, or that I'm missing some low-level abstraction.
bob wrote:I agree. Because most quickly learn that the "object-oriented" approach is NFG for chess, and so they start to get rid of the dynamically created objects and then start writing plain C code that looks like C++.
People often say so, but I've never understood what they mean. Of course, whenever possible, one should avoid using dynamically created objects in performance-critical parts of a program. This is no less true in C than in C++, and has nothing to do with the differences between the two programming languages.

And who said idiomatic C++ has to be object-oriented? C++ was never meant to be an "OO for everything" language, as far as I know.
It is hard to do anything bad in C from a performance perspective, while in C++ it is quite easy.
Is it? Any examples? I've never noticed any such difference. I can't write fast code in either of the two languages, both of them are equally slow in my hands. The main practical difference between C and C++ to me is that I can avoid bugs more easily in C++. Even if I pay some infinitesimal performance penalty for using C++, it is well worth the price.
Yes, you can write a good chess engine in C++, it's been done. But for the most part, such attempts are really C in C++ clothing
I am not sure my program qualifies as a "good chess engine", but at least it is stronger than most. I wouldn't describe it as C in C++ clothing. For one thing, I make very heavy use of the stronger typing in C++. It is true that my program could be translated into plain C without a tremendous effort, but writing the program in the first place would have been more painful and time-consuming in C.

The stronger typing in C++ is a huge advantage over plain C, and for me this is already sufficient reason to prefer C++ (and any program which makes active use of the stronger typing is not C in C++ clothing, even if it never uses templates or classes). I also like to use function overloading, and to use classes to implement crude "poor man's closures", but I could live without these features.

Tord
Richard Allbert
Posts: 792
Joined: Wed Jul 19, 2006 9:58 am

Re: building glaurung2.1 from empty code project

Post by Richard Allbert »

bob wrote:
Richard Allbert wrote:after about 60s searching, you'll find the microsoft site tells you to use setvbuf() instead.

Richard
This is all another idea based on YAPPP. (Yet Another Poor Programming Practice). ....

or by using someone else's code to do something simple, only to find it is broken because they use a different type of I/O and the two approaches are incompatible........

anybody can use read/write without breaking anything.
Thanks for taking the time to answer....

My comment was just to answer the original question - "what is the warning and how do I stop it".

Regarding input, it is interesting what you say - but it isn't easy not to be "yapp" and not use other people's input code / buffering method. I have several c++ textbooks - and spent a lot of frustrated time trying to get peek() to work (as recommended by two of my books) or use the signal class correctly (but the books never explain the Stdlib macros in enough detail).

If you know of a good tutorial link, that would be great :) :)

Richard
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: building glaurung2.1 from empty code project

Post by bob »

Richard Allbert wrote:
bob wrote:
Richard Allbert wrote:after about 60s searching, you'll find the microsoft site tells you to use setvbuf() instead.

Richard
This is all another idea based on YAPPP. (Yet Another Poor Programming Practice). ....

or by using someone else's code to do something simple, only to find it is broken because they use a different type of I/O and the two approaches are incompatible........

anybody can use read/write without breaking anything.
Thanks for taking the time to answer....

My comment was just to answer the original question - "what is the warning and how do I stop it".

Regarding input, it is interesting what you say - but it isn't easy not to be "yapp" and not use other people's input code / buffering method. I have several c++ textbooks - and spent a lot of frustrated time trying to get peek() to work (as recommended by two of my books) or use the signal class correctly (but the books never explain the Stdlib macros in enough detail).

If you know of a good tutorial link, that would be great :) :)

Richard
actually the engine interface howto in winboard is a good start. I helped Tim write that up and it explains read/write. "select()" is a different animal, and I could point you to the right place in Crafty to see how to use it, as well as how to use peekNamedPipe() in windows which accomplishes the same thing.
Richard Allbert
Posts: 792
Joined: Wed Jul 19, 2006 9:58 am

Re: building glaurung2.1 from empty code project

Post by Richard Allbert »

Thanks again,

for others here is the link..

http://www.tim-mann.org/xboard/engine-intf.html

Richard
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: building glaurung2.1 from empty code project

Post by bob »

Tord Romstad wrote:It is strange to yet again find myself defending C++, which is one of the most ugly and unpleasant of the many programming languages I have ever worked with.
Zach Wegner wrote:Some people prefer C. I think it looks a lot nicer, and it's easier to code in.
Looks nicer, yes. Easier to code in? How? Almost everything you do in C you can do in exactly the same way in C++. The only difference I can think of is that you need more typecasts in C++, but in my opinion that is mostly a good thing: If I find that I need to clutter my code with lots of typecasts, it is usually a good sign that I am doing something stuipd, or that I'm missing some low-level abstraction.
bob wrote:I agree. Because most quickly learn that the "object-oriented" approach is NFG for chess, and so they start to get rid of the dynamically created objects and then start writing plain C code that looks like C++.
People often say so, but I've never understood what they mean. Of course, whenever possible, one should avoid using dynamically created objects in performance-critical parts of a program. This is no less true in C than in C++, and has nothing to do with the differences between the two programming languages.

And who said idiomatic C++ has to be object-oriented? C++ was never meant to be an "OO for everything" language, as far as I know.
It is hard to do anything bad in C from a performance perspective, while in C++ it is quite easy.
Is it? Any examples? I've never noticed any such difference. I can't write fast code in either of the two languages, both of them are equally slow in my hands. The main practical difference between C and C++ to me is that I can avoid bugs more easily in C++. Even if I pay some infinitesimal performance penalty for using C++, it is well worth the price.
Take any new OO programmer, and you find them creating and destroying objects everywhere, just because it seems to fit the OOP paradigm. It is the classic "to the man who has a hammer, everything looks like a nail".


Yes, you can write a good chess engine in C++, it's been done. But for the most part, such attempts are really C in C++ clothing
I am not sure my program qualifies as a "good chess engine", but at least it is stronger than most. I wouldn't describe it as C in C++ clothing. For one thing, I make very heavy use of the stronger typing in C++. It is true that my program could be translated into plain C without a tremendous effort, but writing the program in the first place would have been more painful and time-consuming in C.

The stronger typing in C++ is a huge advantage over plain C, and for me this is already sufficient reason to prefer C++ (and any program which makes active use of the stronger typing is not C in C++ clothing, even if it never uses templates or classes). I also like to use function overloading, and to use classes to implement crude "poor man's closures", but I could live without these features.

Tord
Dann Corbit
Posts: 12540
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: building glaurung2.1 from empty code project

Post by Dann Corbit »

Modern C compilers have prototype protection and strong typing also.

However, I prefer C++ for its better abstraction. I think it is not a coincidence that most of the strongest programs for which we have source code are written in C++. It's simply easier to develop in because of the higher levels of abstraction.

However, it is also important to note that C++ does not eliminate complexity, it only hides it.

Strangely, this document:
http://www.csm.ornl.gov/~v8q/Homepage/P ... ntable.pdf
Makes the remarkable claim:
"Introduction of object-oriented technology does not appear to hinder overall productivity on new large commercial projects, but it neither seems to improve it in the first two product generations. In practice, the governing influence may be the business workflow and not the methodology."
which I find hard to fathom. I would be interested in any related studies that are available.

I guess that the bottom line may be that smart people who are well organized are going to write good code wether it is in C or C++ or Lisp or Python or whatever.
Dann Corbit
Posts: 12540
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: building glaurung2.1 from empty code project

Post by Dann Corbit »

Uri Blass wrote:My opinion is that the best way to understand chess program is simply trying to build them from scratch by copying minimal parts that you can compile and understand the parts that you copied and later adding more parts.

I decided in the past to start doing it with glaurung1.2.1 but stopped.

I decided to do it again with Glaurung2.1 and this time I plan to make everything that I do with Glaurung2.1 public.

Note that my knowledge about programming is limited so I may ask a lot of questions that seem to you stupid questions because of commands that I do not understand.

First step is simply generating new empty project with the name Glaurung_learn and adding the file main.cpp to it.

I copy to main.cpp the following code from Glaurung2.1


Code: Select all

#include <iostream>
int main&#40;int argc, char *argv&#91;&#93;)
&#123;
	setbuf&#40;stdin, NULL&#41;;
	setbuf&#40;stdout, NULL&#41;;
	std&#58;&#58;cout.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	std&#58;&#58;cin.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	return 0;
&#125;
1)When I compile it I get warning C4995\6
'setbuf': This function or variable may be unsafe. Consider using setvbuf instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Does it mean that Glaurung is written wrongly or maybe I do not need to care about these warning or maybe there are not going to be warning with the full glaurung program.
The setbuf() function is no more dangerous than std::cout.rdbuf()->pubsetbuf() is. The purpose of both is to modify the way that file operations are buffered. When we use stdin/stdout or cin/cout to read and write from the console, we do not want buffering to be turned on for a chess program that uses either Winboard or UCI protocols. The reason is that buffering may wait to flush until the buffer is full. This makes programs that read and write a bit faster, but it means that reading and writing may not take place synchronously which would be very bad for the Winboard or UCI protocols. For instance, if I say some command that demands a response, we may or may not get a response for a while because the initial request has not been flushed or even if it was flushed the read my not be flushed yet.

In a chess program written in C++, we may like to use both cin/cout and stdin/stdout at our convenience. So if we turn off buffering for both kinds of stream, then we can use both cout and printf() if we like.

All that having been said, setvbuf() is a more modern interface than setbuf() and therefore it might be better. If you are turning buffering off (and in this case we are) there is absolutely no danger to using setbuf.
Except this I have the following questions

2)I am used to use int main(void)
I read the following

"The argument argc is the number of command-line arguments passed to the program. The argument argv is a pointer to an array of strings, where argv[0] is the name you used to run your program from the command-line"

What is the meaning of this command line and can you give me step by step instruction how to run a program from the command line?
If you run a program in C or C++ {and some other languages as well} you can supply runtime arguments to the command line.

In other words, I might start my program like this:
chess.exe
Or like this:
chess.exe -Hash 200MB -HashPawns 32MB
In the first case, if I examine argc I will see 1 and in the second case I will see 5 in argc [assuming that I use the argc/argv interface for main].
3)How can the computer understand setbuf?
When I click help on the word setbuf I find that stdio.h is required header but glaurung does not use stdio.h and it seems that <iostream> is enough to compile it.
The way to understand setbuf is to look in your C book or do a web search like "man setbuf" which will give you sample Unix man pages (which work equally well for Windows compilers when the function is an ANSI/ISO function). You can get the ANSI/ISO C standard for a very low price if you buy the PDF. I think it was $18 when I bought it. This document describes how a compiler that claims to support the ANSI/ISO standard MUST behave. That includes function calls to library functions as well as general behavior of various constructs (IOW, if I initialize a struct, do I need to initialize all the members? This document will answer things like that).
4)I am not sure if I understand exactly what setbuf does except the fact that it does some cleaning to the standard input and standard output files.
The objective of setbuf is to set buffering. In the case of a chess program we want to turn buffering off so that we can run commands synchronously. It is interesting to note that the default behavior of Linux and Windows is different so that chess programs without these buffering commands will behave differently on different platforms. With the setbuf command they will perform the same way.
I guess that the target is that the program will get correct information when it read later some input from the interface or from the user and will forget some information that the user gave before starting to run the program but I am not sure.

An example when things do not work and explanation why they do not work can be productive.

5)I do not understand what is the purpose of the next lines of std:: with rdbuf and pubsetbuf
These commands to the same thing for the standard cin/cout input output files of C++ that setbuf() is doing for the standard C streams.
I do not use these commands and it can be productive if somebody explain to me what they are doing.
Uri
I guess that you should get (at least) the drafts of the ANSI/ISO C and C++ standard. You can find them online for no cost and they will tell you exactly what things like this mean. I would find it incredibly hard to program without them when I come to something that is not familiar. I have standards for many computer languages including esoteric ones like DIBOL.