Question

Which order is the and && operator evaluated

For example the following code

if (float alpha = value1-value2 && alpha > 0.001)
    //do something

threw an exception that alpha is being used without being initiated. I thought the expression left of the && would always initiate the value of alpha first, but it seems I may be wrong

Any idea?

Thanks

Was it helpful?

Solution

This gets parsed as:

if (int alpha = (value1-value2 && (alpha > 0.001)))

... because && has a higher "parsing precedence" than = -- which is probably not what you want. Try:

int alpha = value1-value2; 
if (alpha && (alpha > 0.001))

OTHER TIPS

The bottom line here is that what you are trying to express cannot be possibly expressed by a single logical condition with the declaration of alpha being embedded into it (despite what some other answers claim).

The other answers already explained to you that your condition is not parsed the way you think it is parsed, although many answers make an obvious error of referring to the precedence of = operator in the condition, while in reality there's no = operator there whatsoever. The correct explanation is that when you declare a variable in the if condition, the syntax is that of declaration with an initializer, so the whole thing is parsed the same way as

int alpha = value1 - value2 && alpha > 0.001;

would be parsed, i.e. it is a declaration of int alpha initialized with value1 - value2 && alpha > 0.001. There's no operator = in it. And I hope now you can see why the compiler says that you are reading an uninitialized variable in the initializer expression. The compiler would make the same complaint on the following declaration

int alpha = alpha; // reading uninitialized variable

for the very same reason.

To achieve what you are literally trying to express, you have to either pre-declare alpha

int alpha;
if ((alpha = value1 - value2) && alpha > 0.001) {
  // whatever 
}

or split your if into two

if (int alpha = value1 - value2) 
  if (alpha > 0.001) {
    // whatever 
  }

However, since the second condition already requires alpha to be greater than 0, it doesn't make much sense to even verify the first one, so the most meaningful thing to do would be to just reduce the whole thing to

int alpha = value1 - value2;
if (alpha > 0.001) {
  // whatever 
}

Of course, as others already noted, the comparison of an int value to 0.001 is a valid, but rather weird thing to do. Just do

int alpha = value1 - value2;
if (alpha > 0) {
  // whatever 
}

The left side is always evaluated first. The problem here is operator precedence. See if this doesn't work better:

if ((int alpha = value1-value2) && (alpha > 0.001))

After clarifying how it works (for educative purposes), do not do this. Do not mix variable initialization/assignment and comparisons in the same statement.

It is better if each statement is either a "command" or a "query" alone.

And it is much, much better if a condition inside an "if" is very clearly readable, and unequivocally bool. Not integer, no nothing, just bool.

The first part of your condition is an integer. Then you do an and with a bool. You are forcing a conversion with no need at all. Give if's and conditional operators exactly what they ask for: bools.

Answering the question in the title, it depends on the types of the operands.

For builtin-types, && short-circuits, meaning that the LHS is evaluated, and if it is false then the RHS is not evaluated at all.

For user-defined types which have overloaded operator&&, it does not short-circuit. Both sides are evaluated, in unspecified order, and then the function is called.

I think others have handled the question you need answered, though.

If I'm not mistaken, that operation is undefined. Asigning to to variable and then referring to that same variable in a single statement is undefined.

I generally always use parenthesis just to make my code a little more clear of my intent.

It's evaluated from left to right.

In your case, however the assignment is the last thing to happen and they whole thing would behave as (where alpha is used as part of the calculation to get the result to initialize it):

if (int alpha = (value1-value2 && alpha > 0.001))

You can't mix variable declarations into complex expressions, therefore the following won't compile:

if ((int alpha = value1-value2) && (alpha > 0.001))

Therefore you'll need to split it up to two lines:

int alpha = value1 - value2;
if (alpha > 0.001)
if (int alpha = value1-value2 && alpha > 0.001)

According to the rules would be evaluated in order as

1.  (value1-value2)   [evaluate subtraction]
2.  && (left side)    [test left side]
3.  (alpha > 0.001)   [evaluated only if value-value2 != 0]
4.  && (right side)   [test right side]
4.  alpha =           [assignment]

In step 3, alpha is first evaluated. Since it hasn't been assigned—and maybe not declared, the rules aren't clear on this—it produces an error.

The flaw is that assignment is lower precedence than &&. What still doesn't work, but is closer:

if (int alpha = value1-value2, alpha > 0.001)

Gcc gives error: expected expression before ‘int’. Well maybe it's not closer. With the original statement, gcc says the same thing.

My guess is that it's because you're declaring the storage inside the "if" statement. I didn't even think that would compile.

Try this.

int alpha;
if ((alpha=value1-value2) && alpha>0.001)

But I don't think this is doing what you need. You have alpha as an int, and you're then comparing it to a floating point value. The first part of the && statement will retrun true as long as alpha is not zero and the second part will return true if alpha is greater than 0. So you should probably do this

int alpha;
if ((alpha=value1-value2)>0)

or for much more readable code

int alpha=value1-value2
if (alpha>0)

But to answer your original question: && is executed left to right and short circuited when the answer is obvious. I.e., if the first part of the && is false, the second isn't even evaulated!

Here's an article listing operator precedence and associativity.

From what I can tell, your intent is to declare a temporary, assign it the value of value1-value2, then test the result and enter the if block if it is greater than some value. alpha is being declares as an int, but you seem to be comparing it against a double. alpha should be a double.

Your'e being creative with the use of temporaries. Clear is often better than cute. Do this instead:

double alpha = value1-value2;
if (alpha > 0.001)

According to : http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

- LtR
> LtR
&& LtR
= RtL

given your example

(int alpha = value1-value2 && alpha > 0.001)
(int alpha = (value1-value2) && alpha > 0.001)
(int alpha = (value1-value2) && (alpha > 0.001))
(int alpha = (value1-value2) && (alpha > 0.001))
(int alpha = ((value1-value2) && (alpha > 0.001)))

As written this expression does the following:

  1. Evaluates value1 - value2 and converts it to a bool by implicit comparison against zero - i.e., it is effectively (value1 - value2) != 0
  2. Evaluates alpha > 0.001 after truncating 0.001 to int(0). At this point alpha is not initialized.
  3. Calculates the Logical AND of the previous two evaluations
  4. Converts the Boolean result of the Logical AND back to an integer

I think that this summarizes the rest of the posts. The only reason that I posted a separate answer is that I could not find one that mentioned both when alpha was not initialized and all of the conversions that are occurring here; wallyk's answer is closest.

Of course, the rest of the answers that suggest that you use parentheses and a separate declaration of alpha are exactly what you should do to fix this. Declaring variables within an if statement is part of the language that I haven't found a good use for - declarations within repetition structures seems more appropriate.

The problem is that the statement is evaluating like this:

if (int alpha = (value1-value2 && alpha > 0.001))

Use parentheses to fix the left- and right-hand sides of the && operator:

if ((int alpha = value1-value2) && (alpha > 0.001))

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top