By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,694 Members | 1,294 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,694 IT Pros & Developers. It's quick & easy.

Strange function use

P: n/a
Hi,

in a benchmark I've found an uncommon use of a function.
This is the simplified form:

1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

Could you shed some light on that.

Regards,
Chris
Aug 3 '06 #1
Share this Question
Share on Google+
20 Replies


P: n/a
Christian Christmann wrote:
Hi,

in a benchmark I've found an uncommon use of a function.
This is the simplified form:

1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

Could you shed some light on that.
It's not a /call/ but a declaration - it's say that foo is a function
returning an int. I believe it's also /saying/ that foo takes an unknown
number/type of args - however, as foo's definition is in scope, the compiler
already knows about it ... thus the declaration in line 8 isn't necessary.

--
==============
Not a pedant
==============
Aug 3 '06 #2

P: n/a

Christian Christmann wrote:
1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
int a, b, foo( int );
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.
int foo( ); /*int foo( int );*/

It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.

Aug 3 '06 #3

P: n/a
Christian Christmann wrote:
1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
int a, b, foo(); /*A*/
int a, b = foo(); /*B*/
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }
Differentiate line A and B. A function call occurs at line B.

Aug 3 '06 #4

P: n/a
On Thu, 03 Aug 2006 02:51:39 -0700, lovecreatesbeauty wrote:
>
Christian Christmann wrote:
>1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();

int a, b, foo( int );
>9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

int foo( ); /*int foo( int );*/

It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.
But it's a declaration that deviates from the declaration
given in line 1. There's no function "foo" defined without
any parameters, so why is the declaration from line 8
accepted by a compiler?
Aug 3 '06 #5

P: n/a
Christian Christmann wrote:
On Thu, 03 Aug 2006 02:51:39 -0700, lovecreatesbeauty wrote:
>>
Christian Christmann wrote:
>>1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();

int a, b, foo( int );
>>9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

int foo( ); /*int foo( int );*/

It's not a function use/call, foo() occurs inside a declaration.
It's a function prototype declaration.

But it's a declaration that deviates from the declaration
given in line 1. There's no function "foo" defined without
any parameters, so why is the declaration from line 8
accepted by a compiler?
I think it's because you're saying that it can take any number/type of
args - and that doesn't conflict with the definition - which shows it takes
one arg of type int.

Change line 8 to, say >>8 int a, b, foo(float);

and then there'll be a conflict.

--
==============
Not a pedant
==============
Aug 3 '06 #6

P: n/a
pemo wrote:
Christian Christmann wrote:
Hi,

in a benchmark I've found an uncommon use of a function.
This is the simplified form:

1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

Could you shed some light on that.

It's not a /call/ but a declaration - it's say that foo is a function
returning an int. I believe it's also /saying/ that foo takes an unknown
number/type of args - however, as foo's definition is in scope, the compiler
already knows about it ... thus the declaration in line 8 isn't necessary.
What are the semantics of declaring a function inside
another function ?

Aug 3 '06 #7

P: n/a
sp****@gmail.com wrote:
pemo wrote:
>Christian Christmann wrote:
>>Hi,

in a benchmark I've found an uncommon use of a function.
This is the simplified form:

1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

Could you shed some light on that.

It's not a /call/ but a declaration - it's say that foo is a function
returning an int. I believe it's also /saying/ that foo takes an
unknown number/type of args - however, as foo's definition is in
scope, the compiler already knows about it ... thus the declaration
in line 8 isn't necessary.

What are the semantics of declaring a function inside
another function ?
A declaration of a function is just a /prototype/ - ok?
--
==============
Not a pedant
==============
Aug 3 '06 #8

P: n/a
pemo wrote:
sp****@gmail.com wrote:
What are the semantics of declaring a function inside
another function ?

A declaration of a function is just a /prototype/ - ok?
Let me rephrase. If foo2 is declared inside foo1 are you
allowed to call foo2 only inside foo1 ? If this is so then
since you cannot define foo2 inside foo1 then you cannot
call it at all (you can call some function with the same name
but not the one you declared) which basically means that
the declaration was a waste of time. Have I got it right ?
==============
Not a pedant
==============
Hmmmmmm.

Spiros Bousbouras

Aug 3 '06 #9

P: n/a
pemo wrote:
>>>Christian Christmann wrote:
[...]
8 int a, b, foo();
[...]

A declaration of a function is just a /prototype/ - ok?
No function declaration "is" a prototype, and this
declaration "has" no prototype.

The "prototype" is the description of the function's
argument list, either in a declaration or a definition (a
definition also declares). The prototype part is

int bar(double trouble);
^^^^^^^^^^^^^^

void baz(int x)
^^^^^
{
printf ("%d\n", x);
}

void xyzzy(void);
^^^^

void plugh(const char*, ...);
^^^^^^^^^^^^^^^^

An "old-style" or "K&R" declaration like `int foo();' has
no prototype. Nor does an old-style definition:

double avg(x, y)
double x, y;
{
return (x + y) * 0.5;
}

(Why is it important to keep the nomenclature straight?
Because C's declarations are a source of confusion already,
and we should not add to it by misusing the terminology. If
I feel like calling `extern int x;' a "prototype" for the
variable x, no one will stop me -- but no one will appreciate
my muddying of the waters, either. That's why I never call
`extern int x;' a "prototype," but use the term "beta." ;-)

--
Eric Sosman
es*****@acm-dot-org.invalid
Aug 3 '06 #10

P: n/a
Eric Sosman wrote:
The "prototype" is the description of the function's
argument list, either in a declaration or a definition (a
definition also declares). The prototype part is

int bar(double trouble);
^^^^^^^^^^^^^^
So the return type is not part of the prototype ?
Why not ? I mean since the return type is important
for correct invocation and error checking, it would make
sense to me if it was part of the prototype.

Aug 3 '06 #11

P: n/a
In article <11**********************@75g2000cwc.googlegroups. com>
<sp****@gmail.comwrote:
>Let me rephrase. If foo2 is declared inside foo1 are you
allowed to call foo2 only inside foo1 ?
Not exactly ... but the declaration has block scope, just as
any other declaration at block scope has block scope. Consider,
e.g., the following (bad) code:

void foo1(void) {
double foo2(char *);
double x;

x = foo2("hello world");
...
}

void glork(void) {
int y;

y = foo2(42); /* something is probably wrong here */
...
}

Inside foo1(), we told the compiler "foo2() takes one argument
of type char *, and returns a value of type double".

Inside foo1(), we then call foo2(), with a call that matches the
declaration.

Later, inside glork(), we do *not* tell the compiler anything about
foo2(), and then we call it with one "int" and expect it to return
an "int".

In C99, this call requires a diagnostic, because we are calling a
function we have not declared -- the declaration vanished when it
went out of scope, at the end of foo1().

In C89, no diagnostic is required: the function is implicitly
declared as returning "int". But if foo2() really takes one
"char *" and really returns one "double", we have called it
incorrectly and used a value it never returned, so we should
probably expect things to go wrong.

If foo2() really takes one int and returns one int, we have called
it incorrectly in foo1(), and we can expect things to go wrong
there instead.

A good C89 compiler can (but does not have to) remember how foo2()
was declared inside foo1(), and point out any later conflicts, like
the one in glork(), even after the name has gone out of scope.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.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.
Aug 3 '06 #12

P: n/a
sp****@gmail.com wrote:
Eric Sosman wrote:

> The "prototype" is the description of the function's
argument list, either in a declaration or a definition (a
definition also declares). The prototype part is

int bar(double trouble);
^^^^^^^^^^^^^^


So the return type is not part of the prototype ?
Why not ?
"Why not?" Because of 6.9.1/7:

"The declarator in a function definition specifies the
name of the function being defined and the identifiers
of its parametsrs. [Note omission of return type.] If
the declarator includes a parameter type list, [...]
such a declarator also serves as a function prototype
for later calls to the same function [...]"

Since the declarator "serves as a function prototype" even though
it does not include the function's return type, a prototype does
not include the return type.

... and yet, there seem to be contradictions. 6.2.1/2:

"[...] (A _function prototype_ is a declaration of
a function that declares the types of its parameters.)"

A function declaraTION (not declaraTOR) *does* include the return
type, so this passage says you're right and I'm wrong. Hard to
say which paragraph wins out.

But then there's 6.7.5.3/1:

"A function declarator shall not specify a return type
that is a function type or an array type."

.... implying that a declaraTOR does incorporate the return type
(or the constraint would be vacuous). I think this must be a
typo for declaraTION, because the grammar of 6.7/1 shows that
the return type is part of the declaration-specifiers, separate
from the init-declarator-list that eventually contains the
declarator. Hence, according to the grammar the function's
return type is not part of the declaraTOR, but is part of the
declaraTION.

Other sections of the Standard (6.5.2.2, 7.1.2/1) speak of
function types that "include" prototypes, suggesting that the
prototype is "less than" the complete declaration of the function,
which would feature the return type. That's suggestive, maybe,
but I don't think it's conclusive.

There are also some references to a "function prototype
declarator," a term that doesn't seem to appear in the grammar.

The whole business turns out to be much more confusing (and
even contradictory) than I had thought! Given the uncertainty,
I was rash to jump all over Pemo for misusing (I thought) the
word "prototype;" I apologize to him.

--
Eric Sosman
es*****@acm-dot-org.invalid
Aug 3 '06 #13

P: n/a
Eric Sosman <es*****@acm-dot-org.invalidwrites:
sp****@gmail.com wrote:
[...]
[...]
>So the return type is not part of the prototype ?
Why not ?

"Why not?" Because of 6.9.1/7:

"The declarator in a function definition specifies the
name of the function being defined and the identifiers
of its parametsrs. [Note omission of return type.] If
the declarator includes a parameter type list, [...]
such a declarator also serves as a function prototype
for later calls to the same function [...]"

Since the declarator "serves as a function prototype" even though
it does not include the function's return type, a prototype does
not include the return type.

... and yet, there seem to be contradictions. 6.2.1/2:

"[...] (A _function prototype_ is a declaration of
a function that declares the types of its parameters.)"

A function declaraTION (not declaraTOR) *does* include the return
type, so this passage says you're right and I'm wrong. Hard to
say which paragraph wins out.
Since 6.2.1p2 has "function prototype" in italics, it's the definition
of the term, so I'd say it wins out.

Possibly 6.8.1p7 is badly worded.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 3 '06 #14

P: n/a
"lovecreatesbeauty" <lo***************@gmail.comwrites:
Christian Christmann wrote:
>1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();

int a, b, foo( int );
>9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.

int foo( ); /*int foo( int );*/

It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.
It's a function declaration, but not a prototype. To be a prototype,
it would have to declare the types of the parameters.

With empty parentheses, it specifies that foo takes an fixed but
unspecified number and type(s) of arguments. (To specify that it
takes no arguments, you'd declare "int foo(void)".)

The declaration is legal, but since there's already a visible
prototype for foo, it's completely useless. Putting a function
declaration in a list along with object declarations is legal, but
very odd style. Re-declaring a function inside a function is also
legal, but it's almost never a good idea.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 3 '06 #15

P: n/a
On Thu, 03 Aug 2006 12:17:14 +0200, Christian Christmann
<pl*****@yahoo.dewrote in comp.lang.c:
On Thu, 03 Aug 2006 02:51:39 -0700, lovecreatesbeauty wrote:

Christian Christmann wrote:
1 int foo( int f )
2 {
3 return f;
4 }
5
6 int main( void )
7 {
8 int a, b, foo();
int a, b, foo( int );
9 a = 10;
10 b = foo( a );
11
12 return 0;
13 }

I don't understand the use of function "foo" in line 8.
What's it's purpose? It's called without assigning it's
return value to any variable. Furthermore, I wonder
return value to any variable. Furthermore, I wonder
why this function use is allowed at all. According to
the function prototype "foo" expects an integer argument
that is in line 8 not given. Compiling the code with
"gcc -Wall -ansi" does not issue any warning/errors.
int foo( ); /*int foo( int );*/

It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.

But it's a declaration that deviates from the declaration
given in line 1. There's no function "foo" defined without
any parameters, so why is the declaration from line 8
accepted by a compiler?
Part of your confusion is based on a misunderstanding of this:

int foo(int);

....regardless of the fact that it as at block scope rather than file
scope.

The declaration (not prototype) above declares foo to be a function
that returns an int and accepts an unspecified but fixed number and
type of arguments.

It most specifically is NOT a prototype for a function that takes no
arguments. In another language that stole much of an earlier version
of C, these two declarations are equivalent:

int foo();
int foo(void);

....that is not the case in real, genuine, C.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Aug 3 '06 #16

P: n/a
Jack Klein <ja*******@spamcop.netwrites:
[...]
Part of your confusion is based on a misunderstanding of this:

int foo(int);

...regardless of the fact that it as at block scope rather than file
scope.

The declaration (not prototype) above declares foo to be a function
that returns an int and accepts an unspecified but fixed number and
type of arguments.
"int foo(int);" is both a declaration and a prototype.

The declaration in the original code was "int foo();", which is a
declaration but not a prototype. (Actually it was "int a, b, foo();",
which is an odd way of saying the same thing.)
It most specifically is NOT a prototype for a function that takes no
arguments. In another language that stole much of an earlier version
of C, these two declarations are equivalent:

int foo();
int foo(void);

...that is not the case in real, genuine, C.
Ok, so I think you *meant* to say "int foo();" rather than "int foo(int);".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 3 '06 #17

P: n/a

Keith Thompson wrote:
"lovecreatesbeauty" <lo***************@gmail.comwrites:
int foo( ); /*int foo( int );*/
It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.

It's a function declaration, but not a prototype. To be a prototype,
it would have to declare the types of the parameters.

With empty parentheses, it specifies that foo takes an fixed but
unspecified number and type(s) of arguments. (To specify that it
takes no arguments, you'd declare "int foo(void)".)
I remember that int f(){}; int f2(); are obsolete.

Function prototype is a kind of declaration, right? The function
getchar has no parameters. The code includes <stdio.hbefore calls it,
does not it? I think this is giving the function prototype.

Aug 4 '06 #18

P: n/a
"lovecreatesbeauty" <lo***************@gmail.comwrites:
I remember that int f(){}; int f2(); are obsolete.
No semicolon follows a function definition.
--
Here's a tip: null pointers don't have to be *dull* pointers!
Aug 4 '06 #19

P: n/a
"lovecreatesbeauty" <lo***************@gmail.comwrites:
Keith Thompson wrote:
>"lovecreatesbeauty" <lo***************@gmail.comwrites:
int foo( ); /*int foo( int );*/
It's not a function use/call, foo() occurs inside a declaration. It's a
function prototype declaration.

It's a function declaration, but not a prototype. To be a prototype,
it would have to declare the types of the parameters.

With empty parentheses, it specifies that foo takes an fixed but
unspecified number and type(s) of arguments. (To specify that it
takes no arguments, you'd declare "int foo(void)".)

I remember that int f(){}; int f2(); are obsolete.

Function prototype is a kind of declaration, right?
Right. Specifically, it's "a declaration of a function that declares
the types of its parameters" (quoting the standard).

Now that I think about it, there's a small hole in that definition
for parameterless functions. "int foo(void)" is a prototype, but
"int foo()" is not, but one could argue that neither one "declares
the types of its parameters"; rather, one specifies that there are
no parameters and the other doesn't.
The function
getchar has no parameters. The code includes <stdio.hbefore calls it,
does not it? I think this is giving the function prototype.
Correct, the prototype is in <stdio.h>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 4 '06 #20

P: n/a

Eric Sosman wrote:
sp****@gmail.com wrote:
Eric Sosman wrote:

The "prototype" is the description of the function's
argument list, either in a declaration or a definition (a
definition also declares). The prototype part is

int bar(double trouble);
^^^^^^^^^^^^^^

So the return type is not part of the prototype ?
Why not ?

"Why not?" Because of 6.9.1/7:

"The declarator in a function definition specifies the
name of the function being defined and the identifiers
of its parametsrs. [Note omission of return type.] If
the declarator includes a parameter type list, [...]
such a declarator also serves as a function prototype
for later calls to the same function [...]"
Despite the return type not being mentioned, a function's return
type can't be completely divorced from its declarator:

int fee(int), *fie(int), **foe(int), ***fum(int);

To me it makes just as much sense to say a declarator does
specify its return type, at least implicitly by virtue of
what type specifiers it comes after.
Since the declarator "serves as a function prototype" even though
it does not include the function's return type, a prototype does
not include the return type.

... and yet, there seem to be contradictions. 6.2.1/2:

"[...] (A _function prototype_ is a declaration of
a function that declares the types of its parameters.)"

A function declaraTION (not declaraTOR) *does* include the return
type, so this passage says you're right and I'm wrong. Hard to
say which paragraph wins out.

But then there's 6.7.5.3/1:

"A function declarator shall not specify a return type
that is a function type or an array type."

... implying that a declaraTOR does incorporate the return type
(or the constraint would be vacuous). I think this must be a
typo for declaraTION, because the grammar of 6.7/1 shows that
the return type is part of the declaration-specifiers, separate
from the init-declarator-list that eventually contains the
declarator.
Actually only part of the return type is in the declaration
specifiers:

int foo()[4]; /* yes this isn't legal */

The int-ness is in the declaration specifiers; the
array-sub-4-ness is in the declarator.
Hence, according to the grammar the function's
return type is not part of the declaraTOR, but is part of the
declaraTION.
Here's my guess for the source of the confusion. A
declarator is too small, a declaration is too big.
In the declaration

int blah(int z(void));
-----------
---------------------

there are supposed to be two prototypes (underlined).
The problem is what to say about z: if that's really
the prototype, it's bigger than a declarator, but not
as big as a whole declaration.

The easiest way to make sense of it all is to read the
word "declaration" in 6.2.1/2 as being used informally
rather than in its technically defined sense.

Aug 7 '06 #21

This discussion thread is closed

Replies have been disabled for this discussion.