function prototype vs function declaration

R

Ravishankar S

Dear C Experts,

While prepating a content for a C course,I made section on function
prototypes.
Could you kindly provide me your comments on its correctness. Thank you !

Q12: What is the difference between a function prototype and a function
declaration?

If you get this right, you must have done fair amount of research on C
programming beginning with "K&R" C. It turns out that function declarations
and function prototypes are the same thing in standard C. In K&R C a
function declaration did not need to have the types of its arguments to be
specified.

Thus a declaration like:



int Spi_Tx();



was perfectly acceptable, even though its definition was infact:



int Spi_Tx(uint8 TragetId,uint8 byteArray[],uint16 count)

{



}



It was easy for programmers to call the function with incorrect
parameters which needless to say had disastrous runtime consequences. Thus
ANSI C mandates function prototypes as the method for function declaration.



Regards,
Ravishankar
 
R

Richard Heathfield

Ravishankar S said:

It turns out that function
declarations and function prototypes are the same thing in standard C.

No, it doesn't.

It is true that all function prototypes are function declarations, but it
is not true that all function declarations are function prototypes.

<snip>
 
R

Ravishankar S

Richard Heathfield said:
Ravishankar S said:



No, it doesn't.

It is true that all function prototypes are function declarations, but it
is not true that all function declarations are function prototypes.

<snip>

an example would help here.
 
S

santosh

Ravishankar said:
an example would help here.

int fx();

This is a function declaration, but not a prototype. In fact, argument
checking is turned of for functions declared like this. This is for
backwards compatibility and not recommended for new code. Use:

int fx(void);

or specify the parameters explicitly, as a prototype.
 
R

Ravishankar S

santosh said:
int fx();

This is a function declaration, but not a prototype. In fact, argument
checking is turned of for functions declared like this. This is for
backwards compatibility and not recommended for new code. Use:

int fx(void);

or specify the parameters explicitly, as a prototype.

Thanks.

My amended article would be:

It turns out that there is no difference between function declarations and
function prototypes as far as modern use of C is concerned. When a function
is declared, the number and types of its arguments are also naturally
specified. Such a declaration is also a function prototype.

But it is also allowed to declare a function without specifying its
arguments. In this case the compiler turns off argument checking at the
point of its call. This is meant for backward compatibility (K&R C) should
not be used in normal code. For example:





int fx(); /* declaration , but not a function prototype */



int testFx(void)

{



/* Compiler will not check for argument type match */

if (fx(5) == 10)

{

return 11;



}

return 15;

}



/* Will not get the required arguments ! */

int fx(double a,double b,double c)

{

if((a + b) > c)

return 10;

else

return 11;

}



Thus it is easy for programmers to call the function with incorrect
parameters which needless to say has disastrous runtime consequences. ANSI C
mandates function prototypes as the method for function declaration.
 
R

Richard Heathfield

Ravishankar S said:

My amended article would be:

It turns out that there is no difference between function declarations
and
function prototypes as far as modern use of C is concerned.

I think you should stop writing tutorials and start reading them. There is
a very important distinction between a declaration and a prototype, and
you do your readers a disservice by not making the distinction clear.

What's more, there are (rather recondite) circumstances where you could
conceivably need to eschew the prototype form - I'm thinking particularly
of arrays of pointer to function where not all the functions have the same
type. It is important to know when to use the prototype form (i.e. nearly
always) and when it *might* be a good idea not to.
 
R

Ravishankar S

Richard Heathfield said:
Ravishankar S said:



I think you should stop writing tutorials and start reading them. There is
a very important distinction between a declaration and a prototype, and
you do your readers a disservice by not making the distinction clear.

I am making that distinction.Its only the perception that differs. I was
infact wondering whether I should make that
sentence ("there is a minor yet important difference between function
declaration and function prototype"). But I changed
since I have to make its importance clear.

I am sure 90/100 C progrmmers are not aware of this distiction given now
that function
prototypes are common.
What's more, there are (rather recondite) circumstances where you could
conceivably need to eschew the prototype form - I'm thinking particularly
of arrays of pointer to function where not all the functions have the same
type. It is important to know when to use the prototype form (i.e. nearly
always) and when it *might* be a good idea not to.
I was thinking that my conclusions are fairly accurate!
But I cannot help but note that what you have mentioned may also be achieved
by using void pointer's.
 
S

santosh

Ravishankar said:
Thanks.

My amended article would be:

It turns out that there is no difference between function declarations
and function prototypes as far as modern use of C is concerned.

No. With well written programs there prototypes may serve as
declarations, but this is by no means guaranteed. Saying "no
difference..." is too simplistic.

ANSI C mandates function prototypes as the method for function
declaration.

Recommends, but not mandates.
 
S

santosh

Ravishankar said:
I am making that distinction.Its only the perception that differs. I
was infact wondering whether I should make that
sentence ("there is a minor yet important difference between function
declaration and function prototype"). But I changed
since I have to make its importance clear.

I am sure 90/100 C progrmmers are not aware of this distiction given
now that function
prototypes are common.

However it is better to accurately explain the language as it is
formalised rather than as it might be commonly used. Flushing stdin,
voiding main and using gets seem to be distressingly common in real
world usage, but a tutorial that uses them other than to describe their
dangers, would be considered of very low quality.
I was thinking that my conclusions are fairly accurate!
But I cannot help but note that what you have mentioned may also be
achieved by using void pointer's.

No. void pointers are quite different from function pointers. Please
read a good textbook before continuing on your tutorial.
 
R

Ravishankar S

However it is better to accurately explain the language as it is
formalised rather than as it might be commonly used. Flushing stdin,
voiding main and using gets seem to be distressingly common in real
world usage, but a tutorial that uses them other than to describe their
dangers, would be considered of very low quality.

Point taken. Though this not of the same stature are of writing "void main"
and "fflush(stdin)".
No. void pointers are quite different from function pointers. Please
read a good textbook before continuing on your tutorial.

Please recommend me a good book, other than K&R which covers these points.
Thank you.

If I am not mistaken a void* must be capabale of storing any pointer
(generic pointer) including
a pointer to a function...
 
R

Richard Heathfield

Ravishankar S said:
If I am not mistaken a void* must be capabale of storing any pointer
(generic pointer) including
a pointer to a function...

You are mistaken.

See 3.2.2.3 of C89 - "A pointer to void may be converted to or from a
pointer to any incomplete or object type. A pointer to any incomplete or
object type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer." - or the C99
equivalent, 6.3.2.3. The absence of a definition of the behaviour on
converting a function pointer to void * or back means that that behaviour
is undefined.
 
J

James Kuyper

Ravishankar S wrote:
....
If I am not mistaken a void* must be capabale of storing any pointer
(generic pointer) including a pointer to a function...

You are mistaken. And I'd be very surprised if K&R 2 got that wrong. The
relevant clause is 6.3.2.3p1:

"A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object type
may be converted to a pointer to void and back again; the result shall
compare equal to the original pointer."

A function type is not an incomplete or object type. Therefore, this
clause does not cover pointers to function types; and there is no other
clause which does cover them.

However, p8 says:

"A pointer to a function of one type may be converted to a pointer to a
function of another type and back again; the result shall compare equal
to the original pointer. If a converted pointer is used to call a
function whose type is not compatible with the pointed-to type, the
behavior is undefined."

Therefore, any pointer to function type can be used for the same purpose
with pointers to functions that void* is used for with pointers to
object types. I generally would prefer "void (*)()" for this purpose,
because it's pretty much the most generic type.
 
P

pete

Ravishankar S wrote:
If I am not mistaken a void* must be capabale of storing any pointer
(generic pointer) including
a pointer to a function...

You are mistaken.
It's a common extension,
but not part of the standard C language.
 
S

santosh

Ravishankar said:
Point taken. Though this not of the same stature are of writing "void
main" and "fflush(stdin)".
Perhaps.


Please recommend me a good book, other than K&R which covers these
points. Thank you.

C: A Reference Manual by Harbison & Steele
If I am not mistaken a void* must be capabale of storing any pointer
(generic pointer) including a pointer to a function...

No. A void pointer can only store pointers to object and incomplete
types. Conversion between function and void pointer types is undefined.
Also there is no "generic" function pointer type.
 
R

Ravishankar S

If I am not mistaken a void* must be capabale of storing any pointer
You are mistaken.

See 3.2.2.3 of C89 - "A pointer to void may be converted to or from a
pointer to any incomplete or object type. A pointer to any incomplete or
object type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer." - or the C99
equivalent, 6.3.2.3. The absence of a definition of the behaviour on
converting a function pointer to void * or back means that that behaviour
is undefined.

Thank you. very interesting and enlightening. Does this as corollary mean
that pointers of the type
<type> (*fp)() are legal generic function pointers..??

Finally, any C text book that covers these points explicitly ?
 
P

pete

santosh said:
No. With well written programs there prototypes may serve as
declarations, but this is by no means guaranteed. Saying "no
difference..." is too simplistic.



Recommends, but not mandates.

The C standard explicitly allows the use
of these features in modern C code:

1 The non protoype function declaration
2 What is usually reffered to as "K&R style",
the non protoype function definition.

and also declares them to be obsolescent features.
 
R

Richard Heathfield

James Kuyper said:
Ravishankar S wrote:
...

You are mistaken. And I'd be very surprised if K&R 2 got that wrong.

Brace yourself, then, as you read pp93, 103, 120 and 199, none of which
make it clear that function pointers are not included in the void * magic.
The closest approach is in the tiny-type text on page 199, which
incorrectly singles out object pointers (and thus ignores incomplete
pointers).
 
J

James Kuyper

Richard said:
James Kuyper said:


Brace yourself, then, as you read pp93, 103, 120 and 199, none of which
make it clear that function pointers are not included in the void * magic.
The closest approach is in the tiny-type text on page 199, which
incorrectly singles out object pointers (and thus ignores incomplete
pointers).

I learned C from K&R 1st edition (2nd edition was still years in the
future at that time), and it was excellent. I've never actually read
K&R2; I rely on the standard itself whenever I have a question. I'm a
little disappointed to hear that K&R 2 falls short.
 
S

santosh

Ravishankar said:
Thank you. very interesting and enlightening. Does this as corollary
mean that pointers of the type
<type> (*fp)() are legal generic function pointers..??

Any function pointer type can hold losslessly, the value of any other
function pointer type, but when you deference the pointer to actually
invoke a function, the type of that function and the type of the
function pointer used for calling it must match. Otherwise the
behaviour is undefined.
Finally, any C text book that covers these points explicitly ?

Both _K&R2_ and _C: A Reference Manual_ do so. The fifth edition of the
latter is updated to explain the C99 standard while K&R2 knows only
about the C90 standard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top