Non-Confidential | PDF version | ARM DUI0472J | ||

| ||||

Home > Compiler Coding Practices > Comparison of pure and impure functions |

The two sample routines in the following table illustrate the use of the `__pure`

keyword.

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 5-7 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); } |

The following table shows the corresponding
disassembly of the machine code produced by the compiler for each
of the sample implementations above, where the C code for each implementation has
been compiled using the option `-O2`

, and inlining has
been suppressed.

**Table 5-8 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 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 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)`

.