In many languages assignments are legal in conditions. I never understood the reason behind this. Why would you write:
if (var1 = var2) {
...
}
instead of:
var1 = var2;
if (var1) {
...
}
In many languages assignments are legal in conditions. I never understood the reason behind this. Why would you write:
if (var1 = var2) {
...
}
instead of:
var1 = var2;
if (var1) {
...
}
It can be useful if you're calling a function that returns either data to work on or a flag to indicate an error (or that you're done).
Something like:
while ((c = getchar()) != EOF) {
// process the character
}
// end of file reached...
Personally it's an idiom I'm not hugely fond of, but sometimes the alternative is uglier.
It's more useful if you are calling a function:
if (n = foo())
{
/* foo returned a non-zero value, do something with the return value */
} else {
/* foo returned zero, do something else */
}
Sure, you can just put the n = foo(); on a separate statement then if (n), but I think the above is a fairly readable idiom.
The idiom is more useful when you're writing a while
loop instead of an if
statement. For an if
statement, you can break it up as you describe. But without this construct, you would either have to repeat yourself:
c = getchar();
while (c != EOF) {
// ...
c = getchar();
}
or use a loop-and-a-half structure:
while (true) {
c = getchar();
if (c == EOF) break;
// ...
}
I would usually prefer the loop-and-a-half form.
GCC can help you detect (with -Wall) if you unintentionally try to use an assignment as a truth value, in case it recommends you write
if ((n = foo())) {
...
}
I.e. use extra parenthesis to indicate that this is really what you want.
It's more useful for loops than if statements.
while( var = GetNext() )
{
...do something with var
}
Which would otherwise have to be written
var = GetNext();
while( var )
{
...do something
var = GetNext();
}
In PHP, for example, it's useful for looping through SQL database results:
while ($row = mysql_fetch_assoc($result)) {
// Display row
}
This looks much better than:
$row = mysql_fetch_assoc($result);
while ($row) {
// Display row
$row = mysql_fetch_assoc($result);
}
I find it most useful in chains of actions which often involve error detection, etc.
if ((rc = first_check(arg1, arg2)) != 0)
{
report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
The alternative (not using the assignment in the condition) is:
rc = first_check(arg1, arg2);
if (rc != 0)
{
report error based on rc
}
else
{
rc = second_check(arg2, arg3);
if (rc != 0)
{
report error based on new rc
}
else
{
rc = third_check(arg3, arg4);
if (rc != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
}
}
With protracted error checking, the alternative can run off the RHS of the page whereas the assignment-in-conditional version does not do that.
The short answer is that Expression-oriented programming languages allow more succinct code. The don't force you to separate commands from queries.