I recently just lost some time figuring out a bug in my code which was caused by a typo:
if (a=b)
instead of:
if (a==b)
I was wondering if there is any particular case you would want to assign a value to a variable in a if
statement, or if not, why doesn't the compiler throw a warning or an error?
Yes, you can assign the value of variable inside if.
Using the assignment operator in conditional expressions frequently indicates programmer error and can result in unexpected behavior. The assignment operator should not be used in the following contexts: if (controlling expression)
For example, assignment expressions using the := syntax allow variables to be assigned inside of if statements, which can often produce shorter and more compact sections of Python code by eliminating variable assignments in lines preceding or following the if statement.
Should you define a variable inside IF statement? Honestly, there's no right or wrong answer to this question. JavaScript allows it, so you can make your decision from there.
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
). Some compilers allow avoiding this warning by adding an extra set of parentheses:
if((myBar = getBar())) { //tells the compiler: Yes, I really want to do that assignment!
However, this is ugly and somewhat of a hack, so it's better avoid writing such code.
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 explicitly 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 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 behavior. And there is a lot of good, possible uses for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With