Variable assignment in "if" condition

if (Derived* derived = dynamic_cast<Derived*>(base)) {
   // do stuff with `derived`
}

Though this is oft cited as an anti-pattern ("use virtual dispatch!"), sometimes the Derived type has functionality that the Base simply does not (and, consequently, distinct functions), and this is a good way to switch on that semantic difference.


Here is some history on the syntax in question.

In classical C, error handling was frequently done by writing something like:

int error;
...
if(error = foo()) {
    printf("An error occured: %s\nBailing out.\n", strerror(error));
    abort();
}

Or, whenever there was a function call that might return a null pointer, the idiom was used the other way round:

Bar* myBar;
... //in old C variables had to be declared at the start of the scope
if(myBar = getBar()) {
    //do something with myBar
}

However, this syntax is dangerously close to

if(myValue == bar()) ...

which is why many people consider the assignment inside a condition bad style, and compilers started to warn about it (at least with -Wall). However, this warning can be avoided by adding an extra set of parentheses:

if((myBar = getBar())) {  //tells the compiler: Yes, I really want to do that assignment!

Then C99 came around, allowing you to mix definitions and statements, so many developers would frequently write something like

Bar* myBar = getBar();
if(myBar) {

which does feel awkward. This is why the newest standard allows definitions inside conditions, to provide a short, elegant way to do this:

if(Bar* myBar = getBar()) {

There is no danger in this statement anymore, you explicitely give the variable a type, obviously wanting it to be initialized. It also avoids the extra line to define the variable, which is nice. But most importantly, the compiler can now easily catch this sort of bug:

if(Bar* myBar = getBar()) {
    ...
}
foo(myBar->baz);  //compiler error
//or, for the C++ enthusiasts:
myBar->foo();     //compiler error

Without the variable definition inside the if statement, this condition would not be detectable.

To make a long answer short: The syntax in you question is the product of old C's simplicity and power, but it is evil, so compilers can warn about it. Since it is also a very useful way to express a common problem, there is now a very concise, bug robust way to achieve the same behaviour. And there is a lot of good, possible uses for it.


The assignment operator returns the value of the assigned value. So, I might use it in situation like this:

if (x = getMyNumber())

I assign x to be the value returned by getMyNumber and I check if it's not zero.

Avoid doing that, I gave you an example just to help you understand this.

Edit: adding Just a suggestion.

To avoid such bugs up-to some extends one should write if condition as if(NULL == ptr) instead of if (ptr == NULL) Because When you misspell the equality check operator == as operator =, the compile will throw an lvalue error with if (NULL = ptr), but if (res = NULL) passed by the compiler (which is not what you mean) and remain a bug in code for runtime.

One should also read Criticism regarding this kind of code.