简体   繁体   中英

why doesn't this “if”-statement work?

bool foo( int* p )
{
  return false;
}

int* bar (  )
{
  int* p;
  return p;
}

int main() {

  if ( int* p = bar() && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {

  }

  return 0;
}

I get error: cannot convert 'bool' to 'int*' in initialization with GCC 4.3.4 and VS 2008. If there is only if ( int* p = bar()) everything works fine.

I know i can initialize p before if -statement, but i'm interested in the variant i shown.

int* p = bar() && foo( p )

first evaluates logic expression, then assigns

the same as writing:

int *p = ( bar() && foo(p) );

Assignment operator = has a lower priority than boolean and && thus what you have is this:

int* p = ( bar () && foo(p) )

which is an attempt to assign a bool to an int* variable.

Edit : While it's generally an accepted practice to declare and init variables in the loop's block (like for(int i = 0; i < n; ++i) ) I would strongly advise against such a construct for conditional statements, like if() as it could lead to some very fascinating side-effects that you really don't want to deal with as well as reduce the readability of your code.

Your other variant should work (except I'm not sure you want to compare the result of declaraion int*... to a NULL - that may not be liked by the language), but see my comment above about code clarity

#include <iostream>
bool foo( int* p )
{
  return false;
}

int* bar (  )
{
  int* p;
  return p;
}

int main() {
  int* p;
  if ( (p = bar()) && foo( p ) )
  //if ( ((int* p = bar()) != NULL ) && (foo( p )) ) // another variant
  {

  }

  return 0;
}

OR

int main() {

  if ( int* p = bar()){
      if ( foo( p ) ){ /*do something*/ }
  }
  return 0;
}

it runs

The condition of an if statement can be either a declaration or an expression. A declaration isn't an expression, so you can't combine it with another expression as you are trying to do. In other words, while you were hoping for

(int* p = bar()) && foo(p)

this isn't valid, since int* p = bar() isn't an expression. Instead it is read as the declaration

int* p = (bar() && foo(p))

which isn't valid because the initialiser has the wrong type.

In this case, you're going to have to declare the pointer before the if statement; a couple of options are:

int* p = bar(); // pollutes surrounding scope; maybe wrap in another block
if (p && foo(p)) {}

if (int* p = bar()) {
    if (foo(p)) {  // extra nesting
    }
}

The syntax of an if requires a condition in the parentheses. A condition can be either an expression, or a declaration (of a type with an implicit conversion to bool ); it cannot be a combination of these. In the case of

if ( int* p = bar() && foo( p ) )

, the condition is " int* p = bar() && foo( p ) ", which is a simple declaration of a type int* initialized with bar() && foo( p ) ; since the type of bar() && foo( p ) isn't int* , and can't be implicitly converted into an int* , you have an error.

If you write:

if ( (int* p = bar()) != NULL )

, the opening parentheses mean that this cannot be a declaration (simple or no), and int* p = bar() isn't a legal (sub-)expression.

The critical point to remember is that you can have a declaration, or you can have an expression, but that you can't combine them, and the C++ doesn't allow declarations as part of an expression. (Also: the declaration must have copy initialization:

if ( int* p = bar() )

, direct initialization is not allowed.)

I believe it is the operator precedence. You in fact execute:

if ( int* p = (bar() && foo( p )) )

But what you mean to execute, I believe is:

if ( (int* p = bar()) && foo( p ) )

Which is not exactly the same.

The fact is that you are making an assignment with int* p = bar() and the statement tries to compare two types: int and bool , and that is not possible.

You should assign it before the IF statement.

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM