And more text:
5.6.2 Function and Array Identifiers as Arguments
Function and array identifiers can be specified as argu-
ments to a function. Function identifiers are specified without
parentheses, and array identifiers are specified without
brackets. When so specified, the function or array identifier
is evaluated as the address of that function or array. Also, the
function must be declared or defined, even if its return value
is an integer. Example 5-1 shows how and when to declare
functions passed as arguments, and how to pass them.
Key to Example 5-1:
1 Without being declared in a separate declaration, function
x can be passed in an argument list because its defi-
nition, located before the function caller, serves as its
declaration.
2 Parameters that represent functions can be declared ei-
ther as functions or as pointers to functions. Parameters
that represent arrays can be declared either as arrays or
as pointers to the element type of the array. For example:
fn(int f1(), int f2(), int a1[]) /* f1, f2
declared as */
{...} /* functions; a1
declared */
/* as array of
int. */
fn(int (*f1)(), int (*f2)(), int *a1) /* f1, f2
declared as */
{...} /* pointers to
functions; */
/* a1 declared as
pointer */
/* to int.
*/
When such parameters are declared as functions or
arrays, the compiler automatically converts the corre-
sponding arguments to pointers.
3 Because its function definition is located after the function
caller, function y must be declared before passing it in an
argument list.
4 When passing functions as arguments, do not include
parentheses. Similarly, when specifying arrays, do not
include subscripts.
Example 5-1: Declaring Functions Passed as Arguments
1 int x() { return 25; } /* Function definition and */
int z[10]; /* array defined before use */
2 fn(int f1(), int (*f2)(), int a1[])) /* Function definition */
{
f1(); /* Call to function f1 */
.
.
.
}
void caller(void)
{
3 int y(); /* Function declaration */
.
.
.
4 fn(x, y, z); /* Function call: functions */
/* x and y, and array z */
/* passed as addresses */
.
.
.
}
int y(void) { return 30; } /* Function definition */
6.11.2 Pointer Conversions
Although two types (for example, int and long) can have
the same representation, they are still different types. This
means that a pointer to int cannot be assigned to a pointer
to long without using a cast. Nor can a pointer to a func-
tion of one type be assigned to a pointer to a function of a
different type without using a cast. In addition, pointers to
functions that have different parameter-type information,
including the old-style absence of parameter-type informa-
tion, are different types. In these instances, if a cast is not
used, the compiler issues an error. Because there are align-
ment restrictions on some target processors, access through
an unaligned pointer can result in a much slower access time
or a machine exception.
A pointer to void can be converted to or from a pointer to
any incomplete or object type. If a pointer to any incomplete
or object type is converted to a pointer to void and back, the
result compares equal to the original pointer.
An integral constant expression equal to 0, or such an expres-
sion cast to thevoid * type, is called anull pointer constant. If
a null pointer constant is assigned to or compared for equality
with a pointer, the constant is converted to a pointer of that
type. Such a pointer is called anull pointer, and is guaranteed
to compare unequal to a pointer to any object or function.
An array designator is automatically converted to a pointer to
the array type, and the pointer points to the first element of
the array.
Jeffrey Altman * Sr.Software Designer * Kermit-95 for Win32 and OS/2
The Kermit Project * Columbia University
612 West 115th St #716 * New York, NY * 10025
http://www.kermit-project.org/k95.html * [EMAIL PROTECTED]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]