Consider the following little C program:
int a;
void t( int * p, void (*f) (void *, void *) )
{
if (0 == *p) {
printf( "some output\n" ); /* stop here */
} else {
(*p)--;
(*f)( p, f );
}
}
void main()
{
a = 1;
t( &a, t );
}
To work out the access matrix at the moment the output "some output" appears,
we need to know what users exist. I will take the users to be the function
activations, so we have the following:
- main() suspended at the call t( &a, t ).
- t1, t() called by main and suspended at the call (*f)( p, f ).
- t2, t() called by t and suspended at the call printf().
The objects we will consider are the variables and functions:
- the global variable a.
- the function t().
- for each activation of t, t.p, the parameter p.
- for each activation of t, t.f, the parameter f.
- the function main().
The operations allowed are the right to Call a function and the right to
Access a variable or parameter. The resulting access matrix is:
objects a t() t1.p t1.f t2.p t2.f main()
| | | | | | | |
users ____|_____|_____|_____|_____|_____|_____|_____|
| | | | | | | |
main() | A | C | | | | | C |
____|_____|_____|_____|_____|_____|_____|_____|
| | | | | | | |
t1 | A | C | A | A | | | C |
____|_____|_____|_____|_____|_____|_____|_____|
| | | | | | | |
t2 | A | C | | | A | A | C |
____|_____|_____|_____|_____|_____|_____|_____|
Note that this particular solution ignores the fact that the parameter
f is a pointer to a function while the parameter p is a pointer to an
integer. These parameters convey no new rights in the context of this
program! If, however, a pointer to a local variable was passed from one
function to another, a new access right would be conveyed, and if C had
local functions, so it was not the case that all functions are legally
callable from all other functions, this added complexity would have to be
addressed.