English 中文(简体)
Which side (left or right) of && (and) operator evaluated in C++
原标题:

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

最佳回答

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))
问题回答

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))





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签