471,078 Members | 812 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,078 software developers and data experts.

Correct function prototype format for ANSI C

I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"

So the first format just gives the types, whereas the second format
gives the parameters as well. The second format is just re-stating
the function declaration.

I currently use the first format, and it works on many different C
compilers. I've also seen the second format used in other code, and
that works fine, with GCC at least.

I typically use GCC, but it's important that my code work on other
compilers as well as I maintain code which needs to be portable. My
code is ANSI C; I'm not concerned with C++.

I can't see this mentioned in the FAQ, although it would seem to be an
obvious question (to me at least). Apologies if the answer is equally
obvious.

Roy

Nov 14 '05 #1
13 4107
Roy Hills <ro******@hotmail.com> wrote:
I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"


Both are correct. Which is preferred depends on style; a common argument
against the second type is that the parameter names can cause clashes
with already defined variables, but this is easily circumvented using a
little care, and many people like the extra information.
Note that in the second type, the names in the prototype need not agree
with the names in the definition; only the types must.

Richard
Nov 14 '05 #2
Both format's actually are the same. The nice thing about the 2nd
format is that you are able to tell the reader of a headerfile what the
different variables are.

int myfunc(int, int); /* This is the part the compiler look at */

int myfunc(int apples, int oranges); /* This is much more
understandable, but the compiler sees it as the one above */

--
bjrnove

Nov 14 '05 #3
Roy Hills <ro******@hotmail.com> writes:
I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"
This is correct and sufficient.
2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"


This is also correct, and some prefer it because it provides a clue to
the meaning of the arguments.

The problem with the second form is namespace pollution. You can
usually make sure that the argument names don't conflict at the point
where your code is compiled, but you can't be sure they won't conflict
when third parties writing code that links against your library
include your header.

Some people (including me) prepend argument names in the prototype
with underscores to preserve the documentation value while avoiding
namespace collisions. From a standards point of view, this is
actually worse, because names that begin with underscores are in the
implementation namespace. Still, they are less likely to collide, and
you are more likely to detect a collision during development.

If you provide good documentation for your library, there should be no
need for users to read the headers, and hence no need for prototypes
to include argument names.

DES
--
Dag-Erling Smørgrav - de*@des.no
Nov 14 '05 #4
Richard Bos wrote:
I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"


Both are correct. Which is preferred depends on style; a common argument
against the second type is that the parameter names can cause clashes
with already defined variables


Huh? There are variables sharing namespace with formal parameters of
function prototypes? I have never heard that before. Could you give an
example?
Christian
Nov 14 '05 #5
In message <86************@xps.des.no>
de*@des.no (Dag-Erling Smørgrav) wrote:
Roy Hills <ro******@hotmail.com> writes:
2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"


The problem with the second form is namespace pollution. You can
usually make sure that the argument names don't conflict at the point
where your code is compiled, but you can't be sure they won't conflict
when third parties writing code that links against your library
include your header.


One shouldn't overstate the scale of this problem. It only strikes if you
have the identifier's name already #defined as something odd, or it is a
typedef name. Or an enum, I suppose. But it doesn't matter if you've got a
variable or function called "first" in scope.

The chances of a clash are very slim, as long as you aren't in the habit of
defining a lot of lower case macros. I've never seen it happen in practice.

The Standard Library implementation does need to avoid the possibility
though. The way our library deals with this while keeping the prototypes
clear is very simple:

int div(int /*numer*/, int /*denom*/);

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #6
In message <39*************@individual.net>
Christian Kandeler <ch****************@hob.de_invalid> wrote:
Richard Bos wrote:
2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"


Both are correct. Which is preferred depends on style; a common argument
against the second type is that the parameter names can cause clashes
with already defined variables


Huh? There are variables sharing namespace with formal parameters of
function prototypes? I have never heard that before. Could you give an
example?


The parameters of a prototype _are_ part of the same namespace as all
variables, but the prototype is a new inner scope, so the identifiers
just mask any existing ones. This is the same rule as for normal nested
scopes.

Thus:

extern int i;
{
int i; /* ok - masks global i */
{
int i; /* ok - masks outer i */
int i; /* error - redefinition */
}
}

and the same:

extern int i;
extern void j(void);

void foo(int i, /* ok - masks global i */
int j, /* ok - masks global j */
int i /* error - redefinition */
);

So there's no need to worry about parameter names clashing with already
defined objects or functions.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #7
In article <e3****************@tematic.com>
Kevin Bracey <ke**********@tematic.com> wrote:
The parameters of a prototype _are_ part of the same namespace as all
variables, but the prototype is a new inner scope ... [examples snipped]So there's no need to worry about parameter names clashing with already
defined objects or functions.


Right. Where the problem comes in, however, is when you are not
in control of all the code. For instance, suppose I am the
implementor writing the <string.h> file that you, the user, will
include later. Suppose further that I do this:

/* string.h - ANSI C string functions */
[snippage]
char *strcpy(char *destination, const char *source);
[more snippage]

Now suppose *you*, the user of my implementation, do this:

#define destination Kyoto: the anagram lover's Tokyo!

#include <string.h>

While I would argue that this is not good C code, this *is* *valid*
C code (that you just wrote). The C standard says it has to work.
Unfortunately, it fails, because *I*, the implementor, used the
name "destination" in my prototype for strcpy. When the (actual
text, in this case) file <string.h> is included -- after your
#define -- the strcpy declaration line expands to:

char *strcpy(char *Kyoto: the anagram lover's Tokyo!, const char *source);

and you get a syntax error -- because I used the name "destination"
in my prototype.

The easiest way for me, the implementor, to avoid this problem is for
me to omit the parameter names. Another option is for me to use the
names reserved to me, such as those starting with double underscores:

char *strcpy(char *__destination, const char *__source);

Of course, you -- the user -- had better *not* use names starting
with double-underscore.

If you are a "lone" end-user, in control of your entire portion of
the namespace, you need not worry about this. But what if you are
part of a team, or are a third-party library supplier? What names
will you use? (The C standards have no answer for you; you must
make up your own rules.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #8
Chris Torek wrote:
Kevin Bracey <ke**********@tematic.com> wrote:
The parameters of a prototype _are_ part of the same namespace as all
variables, but the prototype is a new inner scope ...

[examples snipped]
So there's no need to worry about parameter names clashing with already
defined objects or functions.


Right. Where the problem comes in, however, is when you are not
in control of all the code. For instance, suppose I am the
implementor writing the <string.h> file that you, the user, will
include later. Suppose further that I do this:

/* string.h - ANSI C string functions */
[snippage]
char *strcpy(char *destination, const char *source);
[more snippage]

Now suppose *you*, the user of my implementation, do this:

#define destination Kyoto: the anagram lover's Tokyo!


Okay, with suitable macro definitions I can easily invalidate even the most
correct code, but how would you do that with variable names? John Bos
stated that "parameter names [in function prototypes] can cause clashes
with already defined variables". I still don't see how, as the parameter
have almost no scope to speak of and are not used for anything.
Christian
Nov 14 '05 #9
In message <d0*********@news3.newsguy.com>
Chris Torek <no****@torek.net> wrote:
In article <e3****************@tematic.com>
Kevin Bracey <ke**********@tematic.com> wrote:
The parameters of a prototype _are_ part of the same namespace as all
variables, but the prototype is a new inner scope ...

[examples snipped]
So there's no need to worry about parameter names clashing with already
defined objects or functions.


Right. Where the problem comes in, however, is when you are not
in control of all the code.

[snip]

char *strcpy(char *__destination, const char *__source);


I addressed all that in my other post, but thanks for going into more tedious
detail than I was prepared to. As I said, I prefer:

char *strcpy(char * /*destination*/, const char * /*source*/);

Somewhat neater, and it looks prettier in my syntax colouring.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #10
Roy Hills wrote:

I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"

So the first format just gives the types, whereas the second format
gives the parameters as well. The second format is just re-stating
the function declaration.

I currently use the first format, and it works on many different C
compilers. I've also seen the second format used in other code,
and that works fine, with GCC at least.

I typically use GCC, but it's important that my code work on other
compilers as well as I maintain code which needs to be portable.
My code is ANSI C; I'm not concerned with C++.

I can't see this mentioned in the FAQ, although it would seem to
be an obvious question (to me at least). Apologies if the answer
is equally obvious.


My advice is to always use what you call the second format, and to
avoid generating separate prototypes at all as far as possible.
You do this by defining functions before use, and by marking static
all functions that are not to be exported from a particular
compilation unit. Then you only need separate prototypes in header
files (for export) or because of mutual recursion. The prototypes
are more understandable when the parameters have names. Consider:

int divide(int, int);
and
int divide(int dividend, int divisor);

and think about which is more likely to be used correctly.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #11
Roy Hills wrote:
I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"

So the first format just gives the types, whereas the second format
gives the parameters as well. The second format is just re-stating
the function declaration.
...


Both formats are correct. And both have their benefits and drawbacks.
The second format creates more self-documenting declaration, since it
gives you the opportunity to assign informative names to the parameters.
However, it requires more maintenance, since you have to remember to
keep the parameter names synchronized between the declaration and the
definition (it is not required by the language, but it might become
confusing if they get out of sync).

--
Best regards,
Andrey Tarasevich
Nov 14 '05 #12
Roy Hills wrote on 11/03/05 :
I've seen two different function prototype formats used for ANSI C,
and I'm unsure as to which is the correct or preferred one.

1st Format (this is what I use)

type function(type, type, type);

e.g. "int multiply(int, int);"

2nd Format (I've seen this used in other people's code)

type function(type param, type param);

e.g. "int multiply(int first, int second);"

Both are conforming to the standard. The second form has my preference,
because it is 'self-documenting', and I think that is is a Good Thing
(c). BTW, building it only needs a copy from the header of the
definition of the function and to add a trailing semicolon. It's neat
and simple.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++

Nov 14 '05 #13
Christian Kandeler <ch****************@hob.de_invalid> wrote:
Richard Bos wrote:

type function(type param, type param);

e.g. "int multiply(int first, int second);"


Both are correct. Which is preferred depends on style; a common argument
against the second type is that the parameter names can cause clashes
with already defined variables


Huh? There are variables sharing namespace with formal parameters of
function prototypes? I have never heard that before. Could you give an
example?


Sorry; I should have said already #defined constants, of course. For
example

#define size 4

struct list *makelist(int size, int value);

Richard
Nov 14 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Rob Somers | last post: by
6 posts views Thread by dndfan | last post: by
10 posts views Thread by lovecreatesbeauty | last post: by
20 posts views Thread by Christian Christmann | last post: by
29 posts views Thread by Ravishankar S | last post: by
20 posts views Thread by MikeC | last post: by
8 posts views Thread by vaib | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.