0

I have a code like

if (config_atual[6]==config_atual[7]==config_atual[8] || 
    config_atual[1]==config_atual[4]==config_atual[7] || 
    config_atual[2]==config_atual[4]==config_atual[6])
{
   if (config_atual[7]=='X')
       cout << "O Jogador ganhou!" << endl;
   else if (config_atual[7]=='O')
       cout << "O Computador ganhou!" << endl;
}

about a tic-tac-toe game, and whenever I try to compile this line of code, which verifies three of the win conditions (assuming indexes 0,1,2 for first line, 3,4,5 for second and 6,7,8 for last) I get this warning :

suggest parentheses around comparison in operand of '==' [-Wparentheses]

Which I don't understand. What I am doing wrong, config_atual is a char array that contains the present configuration of the playing board.

What does this warning mean, and how can I correct it?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Pedro Calhau
  • 3
  • 1
  • 2

4 Answers4

3

== operator in C++ doesn't work like that. It only allows two operands, which means constructions like a == b == c will not work as you'd expect. Rewrite the condition in a form (a == b && b == c) instead (and mind the parentheses).

r5ha
  • 332
  • 5
  • 13
  • To expand on r5ha's solution and follow user463035818 advice coding in a language is a language. so if your trying to figure out if you have tic tac toe one could say to themselves " if this square is equal (==) to this square and (&&) that square is equal (==) to this square then tic-tac-toe. Might not help you to look at it that way but sure helps me. I break down the sentence in regular language then tr to apply it to coding language – idzireit May 08 '19 at 17:56
  • 2
    In the statement ```a==b==c```, a==b returns a Boolean value, which is then compared against c. If c is some non-boolean type, and there is an implicit conversion between a bool and that type, it will be converted and then compared to c. In this case, ```a==b``` turns into a 1 or a 0, since c is a char, which is treated as an integer. That's the case on x86, at least; I think this might be undefined behavior. – David Dalcino May 08 '19 at 18:04
  • @DavidDalcino: Actually you are correct on the grouping and I wasn't. Pity you didn't write this in the answers section! – Bathsheba May 08 '19 at 18:38
  • Re: "mind the parentheses" -- the parentheses aren't needed. `&&` binds more tightly than `||` (just as `*` binds more tightly than `+` in arithmetic expressions), so `(a && b) || (c && d)` is no different semantically (although it's noisier) than `a && b || c && d`. – Pete Becker May 08 '19 at 20:36
3

The expression config_atual[6]==config_atual[7]==config_atual[8] is grouped as (config_atual[6]==config_atual[7])==config_atual[8]. The part in parentheses is either true or false which is implicitly converted to an int type (or the type of config_atual[8] is that's wider than an int) prior to a second comparison; i.e. config_atual[8]=={1, 0}, where I've used what's in {} to indicate the possibilities. That probably ends up as false.

Occasionally the chaining of == in this manner is useful. But in your case it isn't, and you need to write the expression in a different way;

config_atual[6]==config_atual[7] && config_atual[7]==config_atual[8]

is one such way.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

You can do it like this

if ((config_atual[6]==config_atual[7] && config_atual[7]==config_atual[8]) ||
    (config_atual[1]==config_atual[4] && config_atual[4]==config_atual[7]) ||
    (config_atual[2]==config_atual[4] && config_atual[4]==config_atual[6]))
Jon Guiton
  • 1,360
  • 1
  • 9
  • 11
0
if (((config_atual[6]==config_atual[7])==config_atual[8]) || 
    ((config_atual[1]==config_atual[4])==config_atual[7]) || 
    ((config_atual[2]==config_atual[4])==config_atual[6]))
{
   if (config_atual[7]=='X')
       cout << "O Jogador ganhou!" << endl;
   else if (config_atual[7]=='O')
       cout << "O Computador ganhou!" << endl;
}
Telenoobies
  • 938
  • 3
  • 16
  • 33