* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes.int / sx10c.html
bloba5154e3b31b85d43bb7a996362c91250e1fe0903
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>24.3 Function Pointers and Prototypes</title>
10 <link href="sx10b.html" rev=precedes>
11 <link href="sx11.html" rel=precedes>
12 <link href="sx10.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>24.3 Function Pointers and Prototypes</H2>
17 <p>It's generally a good idea to have a function prototype in scope
18 whenever you call a function.
19 Function prototypes allow the compiler to generate
20 correct code for function calls,
21 and to verify that you've called a function with the correct
22 number and type of arguments.
23 Standard library functions are prototyped
24 by including the relevant standard header files,
25 and it's generally recommended
26 that you write prototype declarations for your own functions, too,
27 usually placing
28 those declarations
29 in your own header files.
30 But what prototype can be used
31 for an indirect function call using a function pointer,
32 such as
33 <pre>
34 (*pfi)(arg1, arg2)
35 </pre>
36 In general, it won't be known until run time
37 what function <TT>pfi</TT> actually points to,
38 so there's no way for the compiler to check the call
39 against the prototype of the actually-called function.
40 (We may know that <TT>pfi</TT> points to
41 <TT>f1</TT>, <TT>f2</TT>, or <TT>f3</TT>,
42 and we may have supplied prototypes for those functions,
43 but that's immaterial.)
44 </p><p>We've seen that when you declare a function pointer,
45 you must declare what the return value
46 of the pointed-to function will be.
47 It's also possible to specify what the prototype
48 of the pointed-to function will be.
49 Here's our earlier declaration of <TT>pfi</TT>,
50 beefed up with a prototype for the arguments:
51 <pre>
52 int (*pfi)(int, int);
53 </pre>
54 Now we know that <TT>pfi</TT> is a pointer to a function,
55 that the function (whatever it is) accepts two <TT>int</TT> arguments,
56 and that the function returns an <TT>int</TT>.
57 Having specified this,
58 the compiler will now be able to do some more checking for us.
59 If we call
60 <pre>
61 (*pfi)(1, 2, 3)
62 </pre>
63 the compiler will complain,
64 because it knows that the function pointed to by <TT>pfi</TT>
65 is supposed to receive
66 two arguments,
67 but we've passed three.
68 The compiler is also in a position to verify
69 that we actually <em>set</em> <TT>pfi</TT>
70 to point to functions that accept two <TT>int</TT> arguments.
71 Our examples so far were in terms of functions which we declared as
72 <pre>
73 extern int f1();
74 extern int f2();
75 extern int f3();
76 </pre>
77 that is, as functions taking unspecified arguments and returning <TT>int</TT>.
78 (Remember, empty parentheses in an external function declaration indicate
79 that the function accepts
80 unspecified arguments,
81 while empty parentheses in a function definition
82 indicate that the function accepts no arguments.)
83 So the compiler won't be able to check the assignments
84 unless we also provide prototypes:
85 <pre>
86 extern int f1(int, int);
87 extern int f2(int, int);
88 extern int f3(int, int);
89 </pre>
90 Now, when we assign
91 <pre>
92 pfi = f1;
93 </pre>
94 the compiler can verify that the function pointer being assigned
95 is to a function which accepts two <TT>int</TT> arguments,
96 as <TT>pfi</TT> expects.
97 If, on the other hand, we declared and assigned
98 <pre>
99 extern int x(int);
100 pfi = x;
101 </pre>
102 the compiler would complain,
103 because <TT>pfi</TT> is supposed to point
104 to a function which accepts two <TT>int</TT> arguments,
105 and the eventual call to <TT>(*pfi)()</TT>
106 is going to be verified to be a call passing two arguments,
107 so assigning <TT>pfi</TT> to point to <TT>x</TT>
108 (which accepts a single argument)
110 incorrect.
111 </p><hr>
113 Read sequentially:
114 <a href="sx10b.html" rev=precedes>prev</a>
115 <a href="sx11.html" rel=precedes>next</a>
116 <a href="sx10.html" rev=subdocument>up</a>
117 <a href="top.html">top</a>
118 </p>
120 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
121 // <a href="copyright.html">Copyright</a> 1996-1999
122 // <a href="mailto:scs@eskimo.com">mail feedback</a>
123 </p>
124 </body>
125 </html>