4.3.3. __pure

A pure function is a function that always returns the same result if it is called with the same arguments.

By default, it is sufficient to evaluate any particular call to a pure function only once. Because the result of a call to the function is guaranteed to be the same for any identical call, each subsequent call to the function in code can be replaced with the result of the original call. This is an instance of the compiler optimization known as Common Subexpression Elimination (CSE).

To instruct the compiler that a function is pure, declare the function as __pure.

The use of the __pure keyword is illustrated in the two sample routines of Table 4.7. Both routines call a function fact to calculate the sum of n! and n!. The fact function 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, the function 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 __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 4.8 shows the corresponding disassembly of the machine code produced by the compiler for each of the sample implementations of Table 4.7, where the C code for each implementation has been compiled using the option -O2.

Table 4.8. 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
    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 the function foo in Table 4-8 where fact is not qualified as __pure, the function fact is called twice, because the compiler does not know the function is a candidate for CSE. In contrast, in the disassembly of foo in Table 4-8 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).

By definition, pure functions cannot have side effects. For example, a pure function cannot read or write global state by using global variables or indirecting through pointers, because accessing global state can violate the rule that the function must return the same value each time when called twice with the same parameters. Therefore, you must use __pure carefully in your programs. Where functions can be declared __pure, however, the compiler can often perform powerful optimizations, such as CSEs.

See __pure in the Compiler Reference Guide for more information about pure functions.

Copyright © 2002-2007 ARM Limited. All rights reserved.ARM DUI 0205H
Non-Confidential