434,694 Members | 1,294 Online
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
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 }56 int main( void )7 {8 int a, b, foo(); int a, b, foo( int ); >9 a = 10;10 b = foo( a );1112 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'sreturn value to any variable. Furthermore, I wonderreturn value to any variable. Furthermore, I wonderwhy this function use is allowed at all. According tothe function prototype "foo" expects an integer argumentthat 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 }56 int main( void )7 {8 int a, b, foo(); int a, b, foo( int ); >>9 a = 10;10 b = foo( a );1112 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'sreturn value to any variable. Furthermore, I wonderreturn value to any variable. Furthermore, I wonderwhy this function use is allowed at all. According tothe function prototype "foo" expects an integer argumentthat 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 }56 int main( void )7 {8 int a, b, foo();9 a = 10;10 b = foo( a );1112 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'sreturn value to any variable. Furthermore, I wonderwhy this function use is allowed at all. According tothe function prototype "foo" expects an integer argumentthat 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 functionreturning an int. I believe it's also /saying/ that foo takes anunknown number/type of args - however, as foo's definition is inscope, the compiler already knows about it ... thus the declarationin 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> Let me rephrase. If foo2 is declared inside foo1 are youallowed 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 (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. Aug 3 '06 #12

 P: n/a sp****@gmail.com wrote: Eric Sosman wrote: > The "prototype" is the description of the function'sargument list, either in a declaration or a definition (adefinition 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 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 San Diego Supercomputer Center <* We must do something. This is something. Therefore, we must do this. Aug 3 '06 #14

 P: n/a "lovecreatesbeauty" 1 int foo( int f )2 {3 return f;4 }56 int main( void )7 {8 int a, b, foo(); int a, b, foo( int ); >9 a = 10;10 b = foo( a );1112 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'sreturn value to any variable. Furthermore, I wonderreturn value to any variable. Furthermore, I wonderwhy this function use is allowed at all. According tothe function prototype "foo" expects an integer argumentthat 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 San Diego Supercomputer Center <* 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

 P: n/a Jack Klein San Diego Supercomputer Center <* We must do something. This is something. Therefore, we must do this. Aug 3 '06 #17

 P: n/a Keith Thompson wrote: "lovecreatesbeauty"

 P: n/a "lovecreatesbeauty"

 P: n/a "lovecreatesbeauty" "lovecreatesbeauty" . -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* 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'sargument list, either in a declaration or a definition (adefinition 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.