<!-- var kmNextPage = "armcc_cihghcac.htm"; var kmPrevPage = "armcc_cjaccjij.htm"; var kmNextPageTitle = "Recommendation of postfix syntax when qualifying f"; var kmPrevPageTitle = "Functions that return the same result when called"; var kmBreadCrumbs = "<a href=\"default.htm\">Home</a> &raquo; <a href=\"armcc_cjafjcfg.htm\">Compiler Coding Practices</a> &raquo; Comparison of pure and impure functions"; kmSetupPaging (); kmNavButtons(); //--> Comparison of pure and impure functions

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 __pureA 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 __pureA pure function declared __pure
fact PROC
...
foo PROC
MOV      r3, r0
PUSH     {lr}
BL       fact
MOV      r2, r0
MOV      r0, r3
BL       fact
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).