Introduction
One of the bad things that the C language allows is setting
variables and calling functions directly in an if statement.
This should be avoided due to how the statement can exit early
stopping some of the logic from happening.
That said, this can also be abused to write more compact code. Not that you should do this because it’s better to have maintainable, rather than clever code.
While how if statements evaluate segments to most programmers.
It’s isn’t necessarily obvious to novice ones. An OR (||) compound
will exit evaluation early if the first part of the evaluation
is true.
if statements are evaluated left to right and stop as soon
as all conditions are met. Meaning, any code after the conditions
are met will not be run. This is a very bad pattern.
Example 1: Function Return
Let’s start with two simple functions to demonstrate.
static bool func_f(void)
{
printf("False\n");
return false;
}
static bool func_t(void)
{
printf("True\n");
return true;
}
First let’s evaluate with func_f first.
if (func_f() || func_t())
;
We’ll end up with the output:
False
True
However, if we flip the order.
if (func_t() || func_f())
;
We end up with only func_t running:
True
In this case, due to all conditions being stratified
once func_t ran, func_f is never called.
You could use pattern instead of putting func_f in
the body of the if statement.
if (!func_t())
func_f();
Example 2: Setting values
Now let’s look at setting a variable within the if statement.
size_t a = 0;
size_t b = 2;
Take this where we call a function that returns true but then
evaluates a variable that is being assigned a value.
if (func_t() || (a = 3))
;
printf("a = %zu\n", a);
In this case we end up with:
True
a = 0
Once again, since the if statement ends once func_t returns
true, a is never set to 3.
The same early exit happens with this as well:
if ((a = 4) || (b = 7))
;
printf("a = %zu, b = %zu\n", a, b);
Where we get:
a = 4, b = 2
Example 3: Setting values passed to functions
When calling a function and setting with an assignment
as a parameter, the assignment happens before the
function is called. However, the if statement
early exit still takes place and it takes place
before the assignment of the second part that is, itself,
a parameter to a function.
First we need another function.
static bool func_v(size_t v)
{
printf("v = %zu\n", v);
return true;
}
This time we’ll use an AND (&&) compound to show
the variables are set before the function call
if (func_v(a = 9) && func_v(b = 8))
;
printf("a = %zu, b = %zu\n", a, b);
And we get this output:
v = 9
v = 8
a = 9, b = 8
Now let’s use an OR.
if (func_v(a = 15) || func_v(b = 15))
;
printf("a = %zu, b = %zu\n", a, b);
Once again, only the first part of the evaluation takes place.
And since the second part does not, not only is func_v not
called a second time, b’s value is not changed.
v = 15
a = 15, b = 8
Conclusion
This should all seem obvious to an experienced programmer but can cause major issues when a novice (or even veteran) tries to be clever. Don’t follow this pattern with C. A pattern similar to this is often used in Lua but this is a case where patterns don’t always translate from one language to another.

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.