Just a quick question, to save me from testing things (although I really should test things to be absolutely certain):
Given the following C code:
r1 = fun1();
r2 = fun2();
if (r1 && r2)
{
// do something
}
Variables r1
and r2
are not being used anywhere else in the code, except in the if (...)
statement. Will both functions be evaluated? I'm worried that the compiler may optimize the code by eliminating r1
and r2
, thus making it look like this:
if (fun1() && fun2())
{
// do something
}
In this case, fun1()
will be evaluated first, and if it returns FALSE
, then fun2()
will not be evaluated at all. This is not what I want, and that's the reason why I'm coding it as in the first code segment.
How can I guarantee that a function will always be evaluated? I thought that this could be done by assigning it to a variable, but I'm concerned about compiler optimization if it sees that this variable is never actually being used later on in the code...
I know this can be achieved by declaring r1
and r2
as volatile
, but I'd like to know if there's a more elegant solution.
Any comments on this issue are greatly appreciated, thanks!
Edit: Thanks to all who replied. I've just used my first code snippet on my project (it's an ARM Cortex-M7-based embedded system). It appears that the compiler does not optimize the code in the way I showed above, and both fun1()
and fun2()
are evaluated (as they should). Furthermore, compiling the code with r1
and r2
declared as volatile
produces exactly the same binary output as when r1
and r2
are just normal variables (i.e., the volatile
keyword doesn't change the compiler output at all). This reassures me that the first code snippet is in fact a guaranteed way of evaluating both functions prior to processing the if (...)
statement that follows.
Assuming the code does not exhibit any undefined behavior, compilers can only perform optimizations that have the same externally viewable behavior as the unoptimized code.
In your example, the two pieces of code do two different things. Specifically, one always calls fun2
while the other calls it conditionally. So you don't need to worry about the first piece of code doing the wrong thing.