Empty parameters list and function definition

  • Follow


Hello,

I read section 6.7.5.3p14 from C99 several times but it looks I missed
something in my understanding...

I put the revelant section for convenience:

  An identifier list declares only the identifiers of the parameters
of the function. An empty
  list in a function declarator that is part of a definition of that
function specifies that the
  function has no parameters. The empty list in a function declarator
that is not part of a
  definition of that function specifies that no information about the
number or types of the
  parameters is supplied.

So to check that I understood correctly this, I wrote and tried to
compile the following code:

--- 8< ---

/*
 * A function declaration with empty identifier list which is part of
 * the definition specifies that the function has no parameters.
 */
int foo()
{
	return 1;
}

/* A function declaration alone with empty list identifier specifies
 * that no information about the number or types of the parameters is
 * supplied.
 */
int bar();

void test(void)
{
	foo(1);			/* should fail */
	bar(1);			/* should be ok */
}

--- >8 ---

Gcc compiles this without any warnings (gcc -Wall -std=c99 -c func.c).
However I would expect gcc to issue an error or a warning since 'foo'
function takes no parameters (in my understanding).

Could anybody enlight me ?

Thanks
0
Reply Francis 11/26/2009 1:29:03 PM

Francis Moreau wrote:
> Hello,
> 
> I read section 6.7.5.3p14 from C99 several times but it looks I missed
> something in my understanding...
> 
> I put the revelant section for convenience:
> 
>   An identifier list declares only the identifiers of the parameters
> of the function. An empty
>   list in a function declarator that is part of a definition of that
> function specifies that the
>   function has no parameters. The empty list in a function declarator
> that is not part of a
>   definition of that function specifies that no information about the
> number or types of the
>   parameters is supplied.
> 
> So to check that I understood correctly this, I wrote and tried to
> compile the following code:
> 
> --- 8< ---
> 
> /*
>  * A function declaration with empty identifier list which is part of
>  * the definition specifies that the function has no parameters.
>  */
> int foo()
> {
> 	return 1;
> }
> 
> /* A function declaration alone with empty list identifier specifies
>  * that no information about the number or types of the parameters is
>  * supplied.
>  */
> int bar();
> 
> void test(void)
> {
> 	foo(1);			/* should fail */
> 	bar(1);			/* should be ok */
> }
> 
> --- >8 ---
> 
> Gcc compiles this without any warnings (gcc -Wall -std=c99 -c func.c).
> However I would expect gcc to issue an error or a warning since 'foo'
> function takes no parameters (in my understanding).
> 
> Could anybody enlight me ?

     A definition is also a declaration, but the two roles are
not always in perfect lock-step.  `int foo() { return 1; }'
defines a function with no parameters, but as a declaration it
gives no information about the parameters.  (Almost none: we
know that foo has no "..." parameters, but that's all.)

     This odd state of affairs may make just a little sense if
you think about the declaration you'd get by chopping off
foo's body and tacking on a semicolon: `int foo();'.  That
declaration gives (almost) no information about foo's parameters,
just like your declaration of bar.  That declaration, roughly
speaking, is the "external appearance" of foo; the additional
details are "private" to the definition itself.

     Recommendation: Don't write old-style function definitions
in new code, and rewrite old-style to new-style whenever you have
a good reason to visit a module containing them.  Note that it is
not always possible to write a portable prototype for an old-style
function: in `int barf(s) unsigned short s; { return s >> 3; }',
an `unsigned short' argument promotes to `int' on some platforms
and to `unsigned int' on others, so we don't know which to write
in a prototype.  Do a full change-over and all will be well.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid
0
Reply Eric 11/26/2009 3:20:12 PM


Francis Moreau <francis.moro@gmail.com> writes:

> I read section 6.7.5.3p14 from C99 several times but it looks I missed
> something in my understanding...
>
> I put the revelant section for convenience:
>
>   An identifier list declares only the identifiers of the parameters
> of the function. An empty
>   list in a function declarator that is part of a definition of that
> function specifies that the
>   function has no parameters. The empty list in a function declarator
> that is not part of a
>   definition of that function specifies that no information about the
> number or types of the
>   parameters is supplied.
>
> So to check that I understood correctly this, I wrote and tried to
> compile the following code:
>
> --- 8< ---
>
> /*
>  * A function declaration with empty identifier list which is part of
>  * the definition specifies that the function has no parameters.
>  */
> int foo()
> {
> 	return 1;
> }
>
> /* A function declaration alone with empty list identifier specifies
>  * that no information about the number or types of the parameters is
>  * supplied.
>  */
> int bar();
>
> void test(void)
> {
> 	foo(1);			/* should fail */
> 	bar(1);			/* should be ok */
> }
>
> --- >8 ---
>
> Gcc compiles this without any warnings (gcc -Wall -std=c99 -c func.c).
> However I would expect gcc to issue an error or a warning since 'foo'
> function takes no parameters (in my understanding).

That might be a good idea, but it does not have to.  Calling a
function with the wrong parameter list is not a constraint violation
unless there is a prototype in scope.  Add (void) to the function
definition and declaration and both will act as a prototype as well.
gcc will then warn you that they are being called incorrectly.

Add -Wstrict-prototypes and you will be told that neither the
definition of foo nor the declaration of bar acts as a prototype.  I
always have this warning on since it lets me know that I have written
a function whose calls won't be checked.

-- 
Ben.
0
Reply Ben 11/26/2009 3:21:50 PM

On Nov 26, 4:21=A0pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Francis Moreau <francis.m...@gmail.com> writes:
> > Gcc compiles this without any warnings (gcc -Wall -std=3Dc99 -c func.c)=
..
> > However I would expect gcc to issue an error or a warning since 'foo'
> > function takes no parameters (in my understanding).
>
> That might be a good idea, but it does not have to. =A0Calling a
> function with the wrong parameter list is not a constraint violation
> unless there is a prototype in scope.

Ah ok, I thought it has to for definition case.

> =A0Add (void) to the function
> definition and declaration and both will act as a prototype as well.
> gcc will then warn you that they are being called incorrectly.
>
> Add -Wstrict-prototypes and you will be told that neither the
> definition of foo nor the declaration of bar acts as a prototype. =A0I
> always have this warning on since it lets me know that I have written
> a function whose calls won't be checked.
>

I'll do the same.

Thanks you
0
Reply Francis 11/30/2009 10:54:44 AM

On Nov 26, 4:20=A0pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>
> =A0 =A0 =A0A definition is also a declaration, but the two roles are
> not always in perfect lock-step. =A0`int foo() { return 1; }'
> defines a function with no parameters, but as a declaration it
> gives no information about the parameters. =A0(Almost none: we
> know that foo has no "..." parameters, but that's all.)

Well still, reading 6.7.5.3p14:

"...An empty list in a function declarator that is part of a
definition of that function specifies that the function has no
parameters..."

it's still unclear if the function has no parameters for the
definition or as a declaration.

>
> =A0 =A0 =A0This odd state of affairs may make just a little sense if
> you think about the declaration you'd get by chopping off
> foo's body and tacking on a semicolon: `int foo();'. =A0That
> declaration gives (almost) no information about foo's parameters,
> just like your declaration of bar. =A0That declaration, roughly
> speaking, is the "external appearance" of foo; the additional
> details are "private" to the definition itself.

ok I think I got your idea, but I'm still not sure this is equivalent
to 6.7.5.3p14.

But it's a good way to remember the rule.

>
> =A0 =A0 =A0Recommendation: Don't write old-style function definitions
> in new code, and rewrite old-style to new-style whenever you have
> a good reason to visit a module containing them. =A0Note that it is
> not always possible to write a portable prototype for an old-style
> function: in `int barf(s) unsigned short s; { return s >> 3; }',
> an `unsigned short' argument promotes to `int' on some platforms
> and to `unsigned int' on others, so we don't know which to write
> in a prototype. =A0Do a full change-over and all will be well.

Indeed.

Thanks
0
Reply Francis 11/30/2009 11:23:45 AM

Francis Moreau <francis.moro@gmail.com> writes:

> On Nov 26, 4:20 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>>
>>      A definition is also a declaration, but the two roles are
>> not always in perfect lock-step.  `int foo() { return 1; }'
>> defines a function with no parameters, but as a declaration it
>> gives no information about the parameters.  (Almost none: we
>> know that foo has no "..." parameters, but that's all.)
>
> Well still, reading 6.7.5.3p14:
>
> "...An empty list in a function declarator that is part of a
> definition of that function specifies that the function has no
> parameters..."
>
> it's still unclear if the function has no parameters for the
> definition or as a declaration.

I think Eric's words are a little confusing.  Let me try to be clear.
There are four things to consider:

1.    int foo() { return 1; }
2.    int foo();
3.    int foo(void) { return 1; }
4.    int foo(void);

All four act as declarations of the function but only 1 and 3 are also
definitions.  3 and 4 also provide a prototype whereas 1 and 2 do not.

2 says the least.  As a declarator with an empty parameter list that
is *not* part of a definition is says nothing about foo's parameters.

1, 3 and 4 all say that foo has no parameters but calls to foo with a
parameter will only be diagnosed in the case of 3 and 4.  A compiler
is permitted to complain about foo(42) after seeing 1, but to do so it
need to distinguish between 1 and 2 because foo(42) is *not* wrong
after seeing only 2.  I don't know a compiler that does this.  For one
thing, it would involve a lot of effort being put into old-style
definitions.

<snip>
-- 
Ben.
0
Reply Ben 11/30/2009 2:11:41 PM

5 Replies
111 Views

(page loaded in 0.113 seconds)

Similiar Articles:













7/24/2012 6:25:09 AM


Reply: