Comparison of pure and impure functions
The use of the __pure keyword is illustrated
in the two sample routines of Table 9. Both routines call a function fact() to
calculate the sum of n! and n!. fact() depends
only on its input argument n to compute n!. Therefore, fact() is
a pure function.
The first routine shows a naive implementation of the function fact(),
where fact() is not declared __pure.
In the second implementation, fact() is qualified
as __pure to indicate to the compiler that it
is a pure function.
Table 9. C code for pure and impure functions
| A pure function not declared __pure | A pure function declared __pure |
|---|
int fact(int n)
{
int f = 1;
while (n > 0)
f *= n--;
return f;
}
int foo(int n)
{
return fact(n)+fact(n);
}
|
int fact(int n) __pure
{
int f = 1;
while (n > 0)
f *= n--;
return f;
}
int foo(int n)
{
return fact(n)+fact(n);
}
|
Table 10 shows
the corresponding disassembly of the machine code produced by the
compiler for each of the sample implementations of Table 9, where the C code
for each implementation has been compiled using the option -O2,
and inlining has been suppressed.
Table 10. Disassembly for pure and impure functions
| A pure function not declared __pure | A pure function declared __pure |
|---|
fact PROC
...
foo PROC
MOV r3, r0
PUSH {lr}
BL fact
MOV r2, r0
MOV r0, r3
BL fact
ADD r0, r0, r2
POP {pc}
ENDP
|
fact PROC
...
foo PROC
PUSH {lr}
BL fact
LSL r0,r0,#1
POP {pc}
ENDP
|
In the disassembly of function foo() in Table 10 where fact() is
not qualified as __pure, fact() is
called twice because the compiler does not know that the function
is a candidate for Common Subexpression Elimination (CSE).
In contrast, in the disassembly of foo() in Table 10 where fact() is
qualified as __pure, fact() is
called only once, instead of twice, because the compiler has been
able to perform CSE when adding fact(n) + fact(n).
See also