Proper way to learn c ?

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Proper way to learn c ?

Post by Don »

I have been considering migrating Komodo to C++, but just sticking my big toe in the water - avoiding most of the features. I wrote a chess program in c++ but it was essentially just a c program compiled with c++.

But I am attracted to C++ for the templates and to c++11 or whatever they are calling it these days for the new features and my belief that they fix some of the warts in the language and make it less likely I will shoot myself in the foot with it.

Has anyone here ventured into that?
mcostalba wrote:
diep wrote: In that sense C++ gets slowly pushed towards a similar small corner, be it a different corner of the programming spectrum, as Fortran.

That's reality.
I agree, but it's a nice corner.

C++ is required by big and technically demanding applications: game developing, platform applications like browsers, databases, wordprocessors, compilers, CAD, etc. A corner where you need skilled and professional (not casual) programmers and where C simply does not seem the best fit due to lesser attitude at modelling the problem space in an effective way at such big and complex scales.

C++ is not for everybody and is not the best choice for every scenario: but this IMHO is not a limit.
Capital punishment would be more effective as a preventive measure if it were administered prior to the crime.
Rein Halbersma
Posts: 751
Joined: Tue May 22, 2007 11:13 am

Re: Proper way to learn c ?

Post by Rein Halbersma »

Don wrote:I have been considering migrating Komodo to C++, but just sticking my big toe in the water - avoiding most of the features. I wrote a chess program in c++ but it was essentially just a c program compiled with c++.

But I am attracted to C++ for the templates and to c++11 or whatever they are calling it these days for the new features and my belief that they fix some of the warts in the language and make it less likely I will shoot myself in the foot with it.

Has anyone here ventured into that?
I have been migrating to C++11 as the features come available within Visual C++, and it really shortens code. But my draughts engine already was a template heavy C++ program. Because you only use the C subset of C++ (I know it's not a proper subset, but roughly speaking it is), I won't talk much about the OO side of C++ or the resource management safety that comes with the new smart pointers. But you still might need to slighly modify your programming style to get the greatest benefit of all the other new features.

First, it is really convenient to be able to declare variables in local scope. So in C++ you don't declare a bunch of variables at the top of a function, but instead only at their first point of use. (NOTE: this point is not followed by Stockfish, sometimes for good reason, but mostly I think it could be improved) E.g.

Code: Select all

for (int i = 0; i <  N; ++i) {
   // bla, local i
}

for (int i = 0; i < N; ++i) {
   // more bla, different local i!
}
Second, if you also get into the habit of initializing variables on first use, you can use the new C++11 auto keyword

Code: Select all

for (auto i = 0; i < N; ++i) {
   // bla, i has type int
}
For int this won't give you much, but as soon as you are doing stuff with the STL, and start looping over iterators, it will be really good. I use auto everywhere.

Third, the ability to use lambdas in combination with the STL is a big boost. So instead e.g. the old C-style qsort with a function pointer to a cmp() function, in C++ you would pass a function object (a struct with a function operator())

Code: Select all

struct comp
{
   bool operator()(Move const& lhs, Move const& rhs) { return lhs.score() < rhs.score(); };
};

// some std::vector moves already initialized
std::sort(moves.begin(), moves.end(), comp()); // comp can be inlined!
The advantage is that the function object gets inlined (which qsort cannot do because it is already compiled) during compilation of the std::sort header. Still, you have to manually write a function object.

Now in C++11 you can define a lambda (basically the function equivalent of a temporary expression) within the sort call and let the compiler generate the function object

Code: Select all

std::sort(moves.begin(), moves.end(), [](Move const& lhs, Move const& rhs) { 
    return lhs.score() < rhs.score(); 
});
A final big improvement with C++11 is the use of move semantics, where much of the copying around of temporary stuff that the old C++ used to do has been eliminated. With both Visual C++ and gcc 4.7 this has been implemented in all the STL containers and algorithms.

There is tons of information available, e.g. this great presentation http://channel9.msdn.com/Events/GoingNa ... and-Beyond by Herb Sutter should give you a much more thorough overview.
lucasart
Posts: 3241
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Proper way to learn c ?

Post by lucasart »

Rein Halbersma wrote: First, it is really convenient to be able to declare variables in local scope. So in C++ you don't declare a bunch of variables at the top of a function, but instead only at their first point of use. (NOTE: this point is not followed by Stockfish, sometimes for good reason, but mostly I think it could be improved) E.g.

Code: Select all

for (int i = 0; i <  N; ++i) {
   // bla, local i
}

for (int i = 0; i < N; ++i) {
   // more bla, different local i!
}
Your knowledge of C is obviously out of date :) But then again if you're a Microsoft user, no wonder: Microsoft didn't implement C99, so what you use in MSVC is the antiquated 1989 C... There were very very few language features added to C99 (the change was mostly adding stuff to the standard library). Here are the main languages changes of C99, inspired by C++ (yes, there are *some* good things in C++ I dare to admit):

1/ for (int i=0;...) This isn't really necessary, but it's a nice to have, and makes typing code comfortable. Being able to declare variables anywhere instead of beginning of block is also nice, and makes code easier/cleaner.

2/ bool: this helps the programmer avoid many errors. For example bool b = my_pawns | your_pawns, returns only true or false. OTOH int b = my_pawns | your_pawns is a disaster, as it takes the 32 lower bits of the total pawn bitboard (I've made that mistake a lot before deciding to use C99's bool feature).

3/ C++ style comments (// instead of /**/): very useful because when you want to comment out a function with /**/ comments inside, you basically have to remove the comments (or de-comment them or make them C++ style). So the only right way is to use C++ style comments IMO.
lucasart
Posts: 3241
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Proper way to learn c ?

Post by lucasart »

Don wrote:I have been considering migrating Komodo to C++, but just sticking my big toe in the water - avoiding most of the features. I wrote a chess program in c++ but it was essentially just a c program compiled with c++.

But I am attracted to C++ for the templates and to c++11 or whatever they are calling it these days for the new features and my belief that they fix some of the warts in the language and make it less likely I will shoot myself in the foot with it.

Has anyone here ventured into that?
Yes, I have done the journey C=>C++ and back C++=>C.

C=>C++
I basically started DoubleCheck in C++ from the beginning. But I was really writing C code and compiling it with g++. More and more I added classes into this, even derived classes and virtual functions, templates, STL. The more I learnt C++ the more I felt like I had to use all those "nice features", until I realized that beyond the syntactic sugar, my program had become a huge piece of crap! I was even throwing an out of time exception from the search (leading to memory leaks and the usual disasters when exceptions are used in C++).

C++=>C
So I decided to close the Pandora box that is C++, and the best way to refrain from using any of these "nice features", is to use pure C. Ever since then my code got: easier to write, easier to read, more robust, and faster. The main difference between C and C++ ere is that in C you focus on the actual problem, whilst in C++ you spend most of your time looking at your code and seeing how you can make even more complex object models that look "so nice".

But when you have a beautiful engine like Komodo all written in C, I don't see how C++ can help you. Basically you could (with a few trivial changes) compile it in C++, but it would just make your program slightly more bloated. To obtain any of the C++ benefits, you'd need to rewrite the whole thing in a much more C++ idiomatic way. Adding new classes and templates on top of pure C code is a bit weird, no ? Anyway, that's my point of view: I'm an all or nothing guy :)

PS whatever you do, make sure you don't overindulge in the OO hype
http://sharpchess.com/?page=50%20Develo ... ct%20Model