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?

 
 
James Kuyper
Guest
Posts: n/a
 
      02-14-2012
On 02/14/2012 05:35 PM, Ben Bacarisse wrote:
> 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.


Calling a function without a declaration in scope is a constraint
violation (6.5.2.2p2). If an actual declaration is present, an implied
one is unnecessary (except when the implicit int rule was in effect,
which it no longer is). So if an implicit declaration is needed, there's
either a constraint violation in the declaration of the function or in
the call of the function.

> 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).


6.5.2.2p1 is the one that seems relevant to me.

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-15-2012
James Kuyper <(E-Mail Removed)> writes:

> On 02/14/2012 05:35 PM, Ben Bacarisse wrote:
>> 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.

>
> Calling a function without a declaration in scope is a constraint
> violation (6.5.2.2p2).


Did you mean p2? p2 is entirely conditional and it might not apply.

> If an actual declaration is present, an implied
> one is unnecessary (except when the implicit int rule was in effect,
> which it no longer is). So if an implicit declaration is needed, there's
> either a constraint violation in the declaration of the function or in
> the call of the function.


I am sure we agree, but I don't find your reasoning easy to follow. In
addition to text that defines a constraint, there must also be an
absence on any text that permits implicit declarations. C90 has almost
exactly the same wording as C99's 6.5.2.2 p1 (and p2 for that matter)
yet C99 and C90 differ in this regard. This is because C90 has wording
(that C99 does not) that defines an explicit declaration in certain
cases.

My point is you can't just say "because of 6.5.2.2p2". Of course, I
also made this mistake by just citing two sections. I should also have
said "and there's nothing that says a declaration will be assumed".

>> 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).

>
> 6.5.2.2p1 is the one that seems relevant to me.


I am not sure it has much relevance (see below) but in any case it can't
rule out all cases on it's own. What's wrong with this:

void (*fp)(void) = function;

in the absence of a declaration for 'function'? 6.5.2.2 p1 does not
prohibit it, but 6.5.1 p2 does. As you can see, I'm retracting my view
that either one is probably enough. I think 6.5.1 p2 is probably enough
on it's own because it says that both the above and

function();

are constraint violations when there's no function declaration in scope.
6.5.2.2 p1 rules out things like this:

int f;
f();

but when f has no declaration at all, f() is not even a function call
expression.

--
Ben.
 
Reply With Quote
 
 
 
 
Peter Nilsson
Guest
Posts: n/a
 
      02-15-2012
James Kuyper <(E-Mail Removed)> wrote:
> 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.


My bad. I was looking at using functions without a declaration in
scope.
e.g...

#include <stdio.h>
int main(void) { foo(); return 0; }
int foo(void) { puts("42"); return 0; }

AFAICS, if a C99+ implementation supports C90 style implicit function
declarations as an extension, then it is not required to issues a
diagnostic since no constraint would be violated.

--
Peter
 
Reply With Quote
 
/dev/phaeton
Guest
Posts: n/a
 
      02-15-2012
On 02/14/2012 03:09 AM, Kaz Kylheku wrote:

> With what warning options?
>
> How about with -Wall and -W?


Honestly? None. I suppose I should start using them.


However, the gist that I'm getting from all this...

It's a good idea to do prototyping, and in the worst case scenario it is
just superfluous. So I will continue to do them.

Sorry to start a lukewarm debate- though it's been quite educational for
me to read through it. I thank you all for that.


Stephen Sprunk 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_.


I will have to re-read the K&R2 usage of "definition" and "declaration".
I seem to be confused on which is which. Thanks for the correction.

Out of time for now... Back to A&P II homework for the rest of the
night. *sigh*

-J
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-15-2012
Peter Nilsson <(E-Mail Removed)> writes:
[...]
> My bad. I was looking at using functions without a declaration in
> scope.
> e.g...
>
> #include <stdio.h>
> int main(void) { foo(); return 0; }
> int foo(void) { puts("42"); return 0; }
>
> AFAICS, if a C99+ implementation supports C90 style implicit function
> declarations as an extension, then it is not required to issues a
> diagnostic since no constraint would be violated.


No, that's still a constraint violation (strictly speaking a syntax
error), and providing an extension doesn't permit a compiler to
omit the required diagnostic.

C99 6.5.1p2:

An identifier is a primary expression, provided it has been
declared as designating an object (in which case it is an lvalue)
or a function (in which case it is a function designator).

with a footnote:

Thus, an undeclared identifier is a violation of the syntax.

A conforming C99+ compiler may support this as an extension, but
it still has to issue a diagnostic.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      02-15-2012
On 2012-02-15, /dev/phaeton <blahbleh666@no_more_spam.hotmail.com> wrote:
> On 02/14/2012 03:09 AM, Kaz Kylheku wrote:
>
>> With what warning options?
>>
>> How about with -Wall and -W?

>
> Honestly? None. I suppose I should start using them.
>
>
> However, the gist that I'm getting from all this...
>
> It's a good idea to do prototyping, and in the worst case scenario it is
> just superfluous. So I will continue to do them.


Or instead of duplicating every declaration, you could just turn on the right
diagnosticxs in the compiler so that you're told when a prototype is necessary,
but missing.

Writing declarations just for the sake of writing declarations can even
lead you to a mistake.

/* forgot to include "foo.h" where foo is declared */

int foo(char *x)
{
}

If you use -Wstrict-prototypes -Wmissing-prototypes, GCC can help you
catch the problem that a declaration was forgotten.

This could indicate that the header file was not included, meaning
that the program is at risk of being inconsistent (definition changes
but the header file declaration does not).

Sometimes this diagnostic indicates that a function which should be static has
been made external.

But if you have a declaration like in the above, then this diagnostic is shut
up:

/* forgot to include "foo.h" where foo is declared */

int foo(char *x);

/*...*/

int foo(char *x)
{
}

The issue is that "foo.h" could have the wrong prototype, causing other
translation units to have incorrect calls to foo.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      02-15-2012
On 02/15/2012 12:51 AM, /dev/phaeton wrote:
> On 02/14/2012 03:09 AM, Kaz Kylheku wrote:
>
>> With what warning options?
>>
>> How about with -Wall and -W?

>
> Honestly? None. I suppose I should start using them.
>
>
> However, the gist that I'm getting from all this...
>
> It's a good idea to do prototyping, and in the worst case scenario it is
> just superfluous.


Keep in mind that your original question, whatever you might have
thought to the contrary, was not actually about whether prototyping
should be done, but about whether it should be done twice - once in a
function declaration, and a second time in the function definition. The
separate declaration often is, as you say, superfluous, and should not
be used if that is the case.

Whether you need to provide a separate declaration is just a matter of
how you organize your code, but you should always use a prototype
whenever you either declare or define a function. They're extremely
useful - they're never superfluous. That's primarily because they allow
the C implementation to recognize certain common kinds of mistakes, and
require it to give you a diagnostic message if you've made one of those
mistakes.

On the separate declaration issue:
The first part of a function's definition is, in itself, a declaration
of the function, so if you never use a function anywhere but in a single
file, and if you define that function prior to any calls to that
function, a separate declaration of the function unnecessarily
complicates your code, and should not be provided. The only case where
this doesn't work is mutually recursive functions - for instance, if
func1() calls func2(), and func2() also calls func1(), at least one of
them must be declared first, with the definition coming later.

For any function which is used in at least one file other than the one
in which it is defined, you should create a header file containing a
declaration of that function, and #include that header file in any file
where that function is used. You should also #include that header file
in the file where the function is defined - that way, if you made a
mistake and the declaration of the function isn't compatible with the
definition of the function, you'll get a diagnostic message telling you so.
--
James Kuyper
 
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