Non-Confidential | PDF version | ARM DUI0375E | ||

| ||||

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 4-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 4-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)`

.