Home > Software engineering >  Keep getting warning "Suggest parentheses around '&&' within '||' for C pro
Keep getting warning "Suggest parentheses around '&&' within '||' for C pro

Time:01-19

 printf(" 1|        %d       |         %d         |       %d    |   %d  |     %d\n", 
    ((coffee_strength == 'm' || coffee_strength == 'M') && 
     (coffee1_type == 'l' || coffee1_type == 'L') || 
     (coffee_strength == 'r' || coffee_strength == 'R') && 
     (coffee1_type == 'b' || coffee1_type == 'B')), 
    ((coffee_maker == 'r' || coffee_maker == 'R') && 
     (coffee1_grindSize == 'c' || coffee1_grindSize == 'C') ||
     (coffee_maker == 'C' || coffee_maker == 'c') &&
     (coffee1_grindSize == 'f' || coffee1_grindSize == 'F')),
    ((coffee_servings >= 1) && (coffee_servings <= 4) &&
     (coffee1_weight >= 0) && (coffee1_weight <= 250) ||
     ((coffee_servings >= 1) && (coffee_servings <= 9) &&
      (coffee1_weight == 500)) || 
     ((coffee_servings >= 10) && (coffee1_weight == 1000))),
    (((coffee_cream == 'y' || coffee_cream == 'Y') &&
      (coffee1_cream == 'y' || coffee1_cream == 'Y') ||
      (coffee_cream == 'n' || coffee_cream == 'N') &&
      (coffee1_cream == 'n' || coffee1_cream == 'N'))),
    ((coffee1_temp >= 60.0) && (coffee1_temp <= 69.9) &&
     (coffee_maker == 'r' || coffee_maker == 'R') || 
     ((coffee1_temp >= 70.0) && (coffee_maker == 'c' ||  coffee_maker == 'C'))));

This is my code that I am trying to compile. Everytime I run it I still get the issue related to bracket placement. I have edited my code many times to try and solve this but the issue still persists. Does anyone have any suggestions as to what I should do?

CodePudding user response:

Operator && has higher precedence than operator ||. Therefore, though legal, the compiler is telling you code that does this:

a && b || c && d

May not be doing what you intended. The compiler will treat that as

(a && b) || (c && d)

but for all it knows, you intended any one of a number of other things.

Perhaps this:

a && (b || (c && d))

or... this:

((a && b) || c) && d

Or maybe... this:

a && (b || c) && d

etc.

It makes a difference, and mistakes like this are common, so although your code will compile, it will do so with warnings when appropriately asked to do so (and it's always appropriate to ask). Not because it is wrong, but rather because you didn't make intent clear enough that the warning monkeys were subdued (which in this case, and most cases, is a good thing) To ensure you get what you expected, the compiler is asking you to clarify your expression via parenthesis. The -Wlogical-op-parentheses, included with -Wall, is the likely candidate telling you this if you're using gcc or clang.

By the looks of it, you've taken up the mantle of trying to address this, but you missed several instances. For example:

((coffee_servings >= 1) && (coffee_servings <= 4) &&
 (coffee1_weight >= 0) && (coffee1_weight <= 250) || // <== here
 ((coffee_servings >= 1) && (coffee_servings <= 9) &&
 (coffee1_weight == 500)) || 
 ((coffee_servings >= 10) && (coffee1_weight == 1000)))

There are others below, which I leave for you to find (they're pretty obvious once you start nesting your parens and realize just how many places a && b || c pops up).

(((coffee_cream == 'y' || coffee_cream == 'Y') &&
  (coffee1_cream == 'y' || coffee1_cream == 'Y') ||
  (coffee_cream == 'n' || coffee_cream == 'N') &&
  (coffee1_cream == 'n' || coffee1_cream == 'N'))),

and here:

((coffee1_temp >= 60.0) && (coffee1_temp <= 69.9) &&
 (coffee_maker == 'r' || coffee_maker == 'R') || // <== here
 ((coffee1_temp >= 70.0) && (coffee_maker == 'c' || coffee_maker == 'C')))

CodePudding user response:

Sorry to say, but that seems like making out everything by looking at space. There are millions of stars, planets, asteroids, comets, meteors.

But I extremely appreciate your effort on formatting. Not a joke.

The problem seems to be here:

                            && (coffee1_temp <= 69.9) &&
     (coffee_maker == 'r' || coffee_maker == 'R') || 
     ((coffee1_temp >= 70.0) && (coffee_maker == 'c' ||  coffee_maker == 'C'))));

Let's expand it:

&& (coffee1_temp <= 69.9) && (coffee_maker == 'r' || coffee_maker == 'R') || ((coffee1_temp >= 70.0) && (coffee_maker == 'c' ||  coffee_maker == 'C'))));

I am not sure what you want to acheive in that line, but here is a example that might fix the error in that line:

&& (coffee1_temp <= 69.9) && ( (coffee_maker == 'r' || coffee_maker == 'R') || ((coffee1_temp >= 70.0) && (coffee_maker == 'c' ||  coffee_maker == 'C')) ) ));

Why does the error happen? You have a a || c && d/a && b || c && d. The compiler warns you since you did not tell it what to do in that situation.

Example: a && c || c && d, What should happen first? c || c or a && c or c || c && d, etc... Extremely confusing...

Edit:

It also seems like you have this on many other places too. You could just use separate if statements to make this clearer...after all it seems like it takes more time to read this than to write a new set of if statements.

I am trying to make it more readable, few more minutes for me please.

Hopefully more readable:

(
    (coffee_strength == 'm' || coffee_strength == 'M')
 && (coffee1_type == 'l' || coffee1_type == 'L')
 || (coffee_strength == 'r' || coffee_strength == 'R')
 && (coffee1_type == 'b' || coffee1_type == 'B')
),



(
    (coffee_maker == 'r' || coffee_maker == 'R')
 && (coffee1_grindSize == 'c' || coffee1_grindSize == 'C')
 || (coffee_maker == 'C' || coffee_maker == 'c')
 && (coffee1_grindSize == 'f' || coffee1_grindSize == 'F')
),



(
    (coffee_servings >= 1)
 && (coffee_servings <= 4)
 && (coffee1_weight >= 0)
 && (coffee1_weight <= 250)
 || (
        (coffee_servings >= 1)
     && (coffee_servings <= 9)
     && (coffee1_weight == 500)
    )
 || (
        (coffee_servings >= 10)
     && (coffee1_weight == 1000)
    )
),



(
    (
        (coffee_cream == 'y' || coffee_cream == 'Y')
     && (coffee1_cream == 'y' || coffee1_cream == 'Y')
     || (coffee_cream == 'n' || coffee_cream == 'N')
     && (coffee1_cream == 'n' || coffee1_cream == 'N')
    )
),



(
    (coffee1_temp >= 60.0)
 && (coffee1_temp <= 69.9)
 && (coffee_maker == 'r' || coffee_maker == 'R')
 || (
        (coffee1_temp >= 70.0)
     && (coffee_maker == 'c' ||  coffee_maker == 'C')
    )
)

Now, is it really hard to make out what the issues are?

Fix, THAT MIGHT NOT BEHAVE AS YOU INTENDED:

(
    (
        (coffee_strength == 'm' || coffee_strength == 'M')
     && (coffee1_type == 'l' || coffee1_type == 'L')
    )
 || (
        (coffee_strength == 'r' || coffee_strength == 'R')
     && (coffee1_type == 'b' || coffee1_type == 'B')
    )
)



(
    (
        (coffee_maker == 'r' || coffee_maker == 'R')
     && (coffee1_grindSize == 'c' || coffee1_grindSize == 'C')
    )
 || (
        (coffee_maker == 'C' || coffee_maker == 'c')
     && (coffee1_grindSize == 'f' || coffee1_grindSize == 'F')
    )
)



(
    (
        (coffee_servings >= 1)
     && (coffee_servings <= 4)
     && (coffee1_weight >= 0)
     && (coffee1_weight <= 250)
    )
 || (
        (coffee_servings >= 1)
     && (coffee_servings <= 9)
     && (coffee1_weight == 500)
    )
 || (
        (coffee_servings >= 10)
     && (coffee1_weight == 1000)
    )
)



(
    (
        (
            (coffee_cream == 'y' || coffee_cream == 'Y')
         && (coffee1_cream == 'y' || coffee1_cream == 'Y')
        )
     || (
            (coffee_cream == 'n' || coffee_cream == 'N')
         && (coffee1_cream == 'n' || coffee1_cream == 'N')
        )
    )
)



(
    (
        (coffee1_temp >= 60.0)
     && (coffee1_temp <= 69.9)
     && (coffee_maker == 'r' || coffee_maker == 'R')
    )
 || (
        (coffee1_temp >= 70.0)
     && (coffee_maker == 'c' ||  coffee_maker == 'C')
    )
)


And as @user3386109 said, you can simplify statements checking for uppercase and lowercase like a == 'A' || a == 'a' to toupper(a) == 'A' using toupper(int c) and tolower(int c) from <ctype.h>

  •  Tags:  
  • Related