C++ Error C2664

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Suji

Re: C++ Error C2664

Post by Suji »

Sven Schüle wrote:
Suji wrote:Thanks Dann and Marco. Your solutions work.
That surprises me. While you may now have satisfied the compiler you probably don't get the semantics right. What atoi() does is that it converts a character string into its numerical value, or zero if the character string contains non-digits. So atoi("123") is 123, atoi("5") is 5, and atoi("5XY") is 0.

From your code example you give I get the strong impression that this is not what you want, or need. It looks like you're parsing an FEN string, and there you most probably have to scan each single character.

So atoi() is simply the wrong function for that purpose. What you need is some conversion of a single character into a value that can be used directly for further processing. In case that value is numeric the solution has already been mentioned in this thread: subtract the character '0' from the input character, and check that the result, considered as an int, is in the range [0..9], otherwise the character was non-numeric.

Coming back to your comment "Your solutions work", I would really like to know whether this means "it compiles" or "it does the right thing at runtime". The latter would indicate that you have a very special case where atoi() returns the right value for you "by accident" (e.g. you are already at the last position of the input string).

Sven
Your concern is understandable. I am indeed parsing a FEN string. When I said that it worked, it indeed meant that it did compile. I have since finished the routine, and tested it on the starting position. It worked. I fear that you might be right in that it will work for some situations and not for others. I will do more testing.

Everybody:
Question: It works in the starting position, and is there a reason it shouldn't work in all positions?
Dann Corbit
Posts: 12541
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: C++ Error C2664

Post by Dann Corbit »

Suji wrote:
Sven Schüle wrote:
Suji wrote:Thanks Dann and Marco. Your solutions work.
That surprises me. While you may now have satisfied the compiler you probably don't get the semantics right. What atoi() does is that it converts a character string into its numerical value, or zero if the character string contains non-digits. So atoi("123") is 123, atoi("5") is 5, and atoi("5XY") is 0.

From your code example you give I get the strong impression that this is not what you want, or need. It looks like you're parsing an FEN string, and there you most probably have to scan each single character.

So atoi() is simply the wrong function for that purpose. What you need is some conversion of a single character into a value that can be used directly for further processing. In case that value is numeric the solution has already been mentioned in this thread: subtract the character '0' from the input character, and check that the result, considered as an int, is in the range [0..9], otherwise the character was non-numeric.

Coming back to your comment "Your solutions work", I would really like to know whether this means "it compiles" or "it does the right thing at runtime". The latter would indicate that you have a very special case where atoi() returns the right value for you "by accident" (e.g. you are already at the last position of the input string).

Sven
Your concern is understandable. I am indeed parsing a FEN string. When I said that it worked, it indeed meant that it did compile. I have since finished the routine, and tested it on the starting position. It worked. I fear that you might be right in that it will work for some situations and not for others. I will do more testing.

Everybody:
Question: It works in the starting position, and is there a reason it shouldn't work in all positions?
Steve's comment is about readability.

Six months from now you may need to enhance this code. Will you clearly know exactly what it is doing?

The more clearly a chess program is written, the faster it advances. Examine (for instance) fruit, glaurung, and scorpio.

You don't need to get tedious:
ChessGameEngine.ConvertBoardPositionUsingSTLStringAsCstring()

but it should be as clear as necessary to make the intentions of the code obvious at a glance.

IMO-YMMV
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: C++ Error C2664

Post by mcostalba »

Suji wrote:
Everybody:
Question: It works in the starting position, and is there a reason it shouldn't work in all positions?
If the fen string would end with a digit then probably you have issues because std::string is not needed to be zero terminated (it doesn't means it is not, only that the standard does not requires it), so perhaps with your STL library implementation it happens to work the same by accident.

But the big point here is that you are silently relying on some non obvious properties of the fen string and of the std::string implementation.

IMHO this is a bad programming habit. We should strive to write code that works as it is written, not because there is something hidden or implicit that makes it work. Code should be self-documenting and obvious. This is a crucial point to keep a manteinable and easy to improve program, otherwise it becames a total crap very very quickly, much more quickly then we would think.
Teemu Pudas
Posts: 88
Joined: Wed Mar 25, 2009 12:49 pm

Re: C++ Error C2664

Post by Teemu Pudas »

mcostalba wrote:
Teemu Pudas wrote:
mcostalba wrote:Just pass a pointer to fix the compile:

Code: Select all

       squareindex += atoi(&fen[i]);
Don't do that - C++ strings aren't required to be null-terminated. Just use c_str().
Yes. You are right. In our case, for fen strings should not occur, but is a good general rule.
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1

Sure, you probably don't use the fullmove counter for anything right now, but say you want to log your games in PGN one day...
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: C++ Error C2664

Post by Sven »

Zach Wegner wrote:
Sven Schüle wrote:
Suji wrote:Thanks Dann and Marco. Your solutions work.
That surprises me. While you may now have satisfied the compiler you probably don't get the semantics right. What atoi() does is that it converts a character string into its numerical value, or zero if the character string contains non-digits. So atoi("123") is 123, atoi("5") is 5, and atoi("5XY") is 0.

From your code example you give I get the strong impression that this is not what you want, or need. It looks like you're parsing an FEN string, and there you most probably have to scan each single character.

So atoi() is simply the wrong function for that purpose. What you need is some conversion of a single character into a value that can be used directly for further processing. In case that value is numeric the solution has already been mentioned in this thread: subtract the character '0' from the input character, and check that the result, considered as an int, is in the range [0..9], otherwise the character was non-numeric.

Coming back to your comment "Your solutions work", I would really like to know whether this means "it compiles" or "it does the right thing at runtime". The latter would indicate that you have a very special case where atoi() returns the right value for you "by accident" (e.g. you are already at the last position of the input string).

Sven
No, atoi("5XY") is 5. I still think this solution is bad, because it relies on the fact that FENs can only have one consecutive digit in a row, which most likely will not be obvious from the code. *c - '0' is much simpler and better IMO.
Oops, you are right. In fact I did not know this atoi() definition yet. I guess the reason why I ignored this for about 20 years is that this definition is so ugly and unintuitive for me that I would never even think of relying on it in my software. If a character string is not completely numeric but begins with a number, like in "5XY", then it does not make any sense for me to convert it into the number at its beginning, and consider this number to be the "numerical value" of the whole string. And if the function atoi() provides such a conversion then I can't imagine any useful application of it in well-written software.

All the other arguments against using atoi() in this example are still valid, of course. The most convincing one for me is "readability".

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

Re: C++ Error C2664

Post by Dann Corbit »

Sven Schüle wrote:
Zach Wegner wrote:
Sven Schüle wrote:
Suji wrote:Thanks Dann and Marco. Your solutions work.
That surprises me. While you may now have satisfied the compiler you probably don't get the semantics right. What atoi() does is that it converts a character string into its numerical value, or zero if the character string contains non-digits. So atoi("123") is 123, atoi("5") is 5, and atoi("5XY") is 0.

From your code example you give I get the strong impression that this is not what you want, or need. It looks like you're parsing an FEN string, and there you most probably have to scan each single character.

So atoi() is simply the wrong function for that purpose. What you need is some conversion of a single character into a value that can be used directly for further processing. In case that value is numeric the solution has already been mentioned in this thread: subtract the character '0' from the input character, and check that the result, considered as an int, is in the range [0..9], otherwise the character was non-numeric.

Coming back to your comment "Your solutions work", I would really like to know whether this means "it compiles" or "it does the right thing at runtime". The latter would indicate that you have a very special case where atoi() returns the right value for you "by accident" (e.g. you are already at the last position of the input string).

Sven
No, atoi("5XY") is 5. I still think this solution is bad, because it relies on the fact that FENs can only have one consecutive digit in a row, which most likely will not be obvious from the code. *c - '0' is much simpler and better IMO.
Oops, you are right. In fact I did not know this atoi() definition yet. I guess the reason why I ignored this for about 20 years is that this definition is so ugly and unintuitive for me that I would never even think of relying on it in my software. If a character string is not completely numeric but begins with a number, like in "5XY", then it does not make any sense for me to convert it into the number at its beginning, and consider this number to be the "numerical value" of the whole string. And if the function atoi() provides such a conversion then I can't imagine any useful application of it in well-written software.

All the other arguments against using atoi() in this example are still valid, of course. The most convincing one for me is "readability".

Sven
You do have a good point that atoi() does not handle out of bounds data well.

For instance, if you are off by one and reading the second 'e' of e2e4 you will get a zero. Probably not what is wanted. Hence, functions that can tell you something is wrong with the input are probably a much better idea.