Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Function Prototypes: Necessary or just good practice?

Reply
Thread Tools

Function Prototypes: Necessary or just good practice?

 
 
/dev/phaeton
Guest
Posts: n/a
 
      02-14-2012
In K&R2, function definitions in a program were preceded by a function
prototype, i.e.:

int my_function(int variable1, int variable2);

Then somewhere down the line is the actual definition of the function
itself:

int my_function(int variable1, int variable2)
{
do;
some;
stuff;
return (some_value);
}


However, I've noticed that if I omit the function prototype, the program
compiles (with gcc 4.6.x at least) and runs just fine. Is this
something that's now acceptable in ANSI standards since K&R2 was
printed? Or is this 'compiler forgiveness'- letting me do something I
probably shouldn't?


Thanks.

-J
 
Reply With Quote
 
 
 
 
Johann Klammer
Guest
Posts: n/a
 
      02-14-2012
/dev/phaeton wrote:
> In K&R2, function definitions in a program were preceded by a function
> prototype, i.e.:
>
> int my_function(int variable1, int variable2);
>
> Then somewhere down the line is the actual definition of the function
> itself:
>
> int my_function(int variable1, int variable2)
> {
> do;
> some;
> stuff;
> return (some_value);
> }
>
>
> However, I've noticed that if I omit the function prototype, the program
> compiles (with gcc 4.6.x at least) and runs just fine. Is this something
> that's now acceptable in ANSI standards since K&R2 was printed? Or is
> this 'compiler forgiveness'- letting me do something I probably shouldn't?
>
>
> Thanks.
>
> -J


Hello,

in a sense your function definition includes the prototype..
As long as any function that calls it is further down the file,
there will not be any problems.

methinks the prototype(only) would be

int my_function(int, int);

and the definition(minimum required) would be:

my_function(variable1, variable2)
{

}

if there's no prototype, AFAIK
some assumptions regarding the types
are made by the compiler. It assumes int as return type
and ints for any parameters specified (unless it's pointers
then it is pointers to int).
so for above example you get something like the following:

int my_function(int,int)

which just happens to be your original declaration.

This raises a question..
Why prototypes?
Including type information in function definitions increases
readability and is completely alright for static functions
as long as any functions that call it are further down the file.
However, this usually reverses the 'logical' order of function
definitions inside a file, so lowest level functions show up
first.
That is why most people explicitly specify prototypes also
for static functions.

They are usually needed for extern functions to be used with
header files, of course.

Warning: above is mostly how I understand C99, I do not know
too much about K&R C. So take it with a grain of salt.

bye,
JK
 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-14-2012
On 13-Feb-12 23:05, /dev/phaeton wrote:
> In K&R2, function definitions in a program were preceded by a function
> prototype, i.e.:
>
> int my_function(int variable1, int variable2);


Note this is a prototyped function _declaration_.

> Then somewhere down the line is the actual definition of the function
> itself:
>
> int my_function(int variable1, int variable2)
> {
> do;
> some;
> stuff;
> return (some_value);
> }


This is a prototyped function _definition_. Note that a definition
declares the function as well, if that hasn't already been done.

> However, I've noticed that if I omit the function prototype,


ITYM the function declaration.

> the program compiles (with gcc 4.6.x at least) and runs just fine.


Since you don't include the rest of the program's source, we don't know
if this is luck or you just didn't happen to do something wrong.

Lots of stuff happens to work "just fine" on some implementations even
though that may not be guaranteed.

> Is this something that's now acceptable in ANSI standards since K&R2
> was printed? Or is this 'compiler forgiveness'- letting me do something I
> probably shouldn't?


It's not new; in fact, it's the old (pre-ANSI) way of doing things.

K&R C allowed calling functions that hadn't previously been declared,
which caused an implicit declaration of a function by that name. This
was deprecated by ANSI. Unless you _know_ you are coding for a platform
for which there is no C89 (or later) compiler, which should be
incredibly rare these days, you should always declare your functions.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Philip Lantz
Guest
Posts: n/a
 
      02-14-2012
/dev/phaeton wrote:
> In K&R2, function definitions in a program were preceded by a function
> prototype, i.e.:
>
> int my_function(int variable1, int variable2);
>
> Then somewhere down the line is the actual definition of the function
> itself:
>
> int my_function(int variable1, int variable2)
> {
> do;
> some;
> stuff;
> return (some_value);
> }
>
>
> However, I've noticed that if I omit the function prototype, the program
> compiles (with gcc 4.6.x at least) and runs just fine. Is this
> something that's now acceptable in ANSI standards since K&R2 was
> printed? Or is this 'compiler forgiveness'- letting me do something I
> probably shouldn't?


1. If all calls to the function are after the definition, then the
definition acts as a prototype and there is no problem. The following
points are based on the assumption that there is a call before the
definition.

2. It's allowed by the C90 standard, as long as the function returns int
and the correct parameters are passed. The number and types of
parameters are not checked, and the behavior is undefined if they don't
match the function definition (based on a non-trivial set of matching
rules in the standard).

3. It's not allowed by C99 and later standards. Many compilers may still
support it, though, for backward compatibility.

4. It is letting you do something you probably shouldn't--even when the
behavior is allowed and defined by the standard, it is much better to
always have a prototype-style definition or declaration of every
function before it is called.
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      02-14-2012
On 2012-02-14, /dev/phaeton <blahbleh666@no_more_spam.hotmail.com> wrote:
> In K&R2, function definitions in a program were preceded by a function
> prototype, i.e.:


It's good practice to declare functions before calling them.
Calling undeclared functions is a deprecated language feature.

However, there is often no need for prototypes within one translation unit,
because you can organize the code so that each function is defined prior to any
calls to the function. A function definition serves as a prototype declaration.

This arrangement is impossible when you have mutual recursion among
two or more functions. Some of them have to be prototyped.

> However, I've noticed that if I omit the function prototype, the program
> compiles (with gcc 4.6.x at least) and runs just fine.


With what warning options?

How about with -Wall and -W?
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-14-2012
Johann Klammer <(E-Mail Removed)1.net> writes:

> /dev/phaeton wrote:
>> In K&R2, function definitions in a program were preceded by a function
>> prototype, i.e.:
>>
>> int my_function(int variable1, int variable2);
>>
>> Then somewhere down the line is the actual definition of the function
>> itself:
>>
>> int my_function(int variable1, int variable2)
>> {

<snip>
>> }
>>

<snip>
> in a sense your function definition includes the prototype..
> As long as any function that calls it is further down the file,
> there will not be any problems.
>
> methinks the prototype(only) would be
>
> int my_function(int, int);


That's fine, but so is the longer form with named parameters given by
the OP.

> and the definition(minimum required) would be:
>
> my_function(variable1, variable2)
> {
>
> }


No, that's not allowed. First, in C99, you are not allowed to omit the
return type. Even in older C (where the implicit int return is OK), the
parameters must be declared either in the function declarator (that's
what the OP did and is the modern way) or in a separate declaration list
between the ) and the { like this:

my_function(variable1, variable2)
int variable1, variable2;
{
}

This last form is old K&R C and was still legal in C90. Add "int" for
the return type and it's still legal in C99 (though very bad style
nowadays).

> if there's no prototype, AFAIK
> some assumptions regarding the types
> are made by the compiler. It assumes int as return type


In C90 ("ANSI C") yes. In C99 implicit declarations are not permitted.

> and ints for any parameters specified (unless it's pointers
> then it is pointers to int).
> so for above example you get something like the following:
>
> int my_function(int,int)


No, you get int my_function() and there is a real difference. You are
confusing what are called the default argument promotions with an
implied prototype. When there's no prototype, the compiler assumes
nothing about the parameters, but it does perform certain type
conversions in a call. If the compiler assumed the prototype you've
written, a call like my_function(1.0, 2.0) would have the
arguments converted, but that's not what happens. The details hardly
matter, since this is only important for very old code.

> which just happens to be your original declaration.
>
> This raises a question..
> Why prototypes?
> Including type information in function definitions increases
> readability and is completely alright for static functions
> as long as any functions that call it are further down the file.


They (prototypes) also cause correct conversion of function arguments.
You don't get that with non-prototype declarations or definitions.

<snip>
--
Ben.
 
Reply With Quote
 
Ralf Damaschke
Guest
Posts: n/a
 
      02-14-2012
Ben Bacarisse <(E-Mail Removed)> wrote:

> No, that's not allowed. First, in C99, you are not allowed to
> omit the return type. Even in older C (where the implicit int
> return is OK), the parameters must be declared either in the
> function declarator (that's what the OP did and is the modern
> way) or in a separate declaration list between the ) and the {
> like this:
>
> my_function(variable1, variable2)
> int variable1, variable2;
> {
> }
>


I still remember that I used to write
"main (argc, argv) char **argv; { /* some work */ return 0; }".

And C90 did not break such existing code omitting an implicit int
declaration:

| If the declarator includes an identifier list, the types of the
| parameters may be declared in a following declaration list. Any
| parameter that is not declared has type int.

-- Ralf
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      02-14-2012
Ben Bacarisse <(E-Mail Removed)> wrote:
> In C99 implicit declarations are not permitted.


They're no longer required, but if a C99+ implementation
decides to support them anyway, no diagnostic is required
for their use.

....
> They (prototypes) also cause correct conversion of function
> arguments. ...


Unless the prototype ends with ellipsis and you're back to
default argument promotions for the unnamed arguments.

--
Peter
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-14-2012
On 02/14/2012 04:47 PM, Peter Nilsson wrote:
> Ben Bacarisse <(E-Mail Removed)> wrote:
>> In C99 implicit declarations are not permitted.

>
> They're no longer required, but if a C99+ implementation
> decides to support them anyway, no diagnostic is required
> for their use.


Its a constraint violation - 6.7.2p2: "At least one type specifier shall
be given in the declaration specifiers in each declaration,
and in the specifier-qualifier list in each struct declaration and type
name." Therefore a diagnostic is required.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-14-2012
James Kuyper <(E-Mail Removed)> writes:

> On 02/14/2012 04:47 PM, Peter Nilsson wrote:
>> Ben Bacarisse <(E-Mail Removed)> wrote:
>>> In C99 implicit declarations are not permitted.

>>
>> They're no longer required, but if a C99+ implementation
>> decides to support them anyway, no diagnostic is required
>> for their use.

>
> Its a constraint violation - 6.7.2p2: "At least one type specifier shall
> be given in the declaration specifiers in each declaration,
> and in the specifier-qualifier list in each struct declaration and type
> name." Therefore a diagnostic is required.


I don't think he's talking about implicit int. I certainly wasn't.

However, I still think it's a constraint violation. I think 6.5.1 p2
and 6.5.2.2 p1 conspire to make it so (either on it's is probably
enough).

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem using the strptime function on HPUXThe strptime function works just kongkolvyu C Programming 4 01-04-2006 11:03 PM
xsl:function does abort just after the call of the function schaf XML 0 05-29-2005 03:21 PM
cookie handling - is there a list of *necessary* cookies ?? cookie-monster Firefox 1 03-05-2005 03:40 AM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
need to find way to just ring phone (voice / data transmission not necessary) Thomas Miller VOIP 5 12-11-2004 07:35 AM



Advertisments