3

Another newbie question:

int foo();  // outer foo function
int main() {
    int foo(); // inner foo function
    cout << foo() << endl;
}

int foo() { // one definition
    return 42;
}

From my understanding, an inner declaration of either function or object will hide outer one, if any.
So the above outer foo() and inner foo() should be two distinct functions.
But they are sharing one definition, which seems confusing. Is it legal that two distinct functions share one definition? How about two distinct object variables? (This is C++ question but the syntax seems also fits C.)

Edit:

It is verified that outer and inner foo are the same funciton using pointer to function:

pf_outer = 0x400792

pf_inner = 0x400792
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • your inner `foo()` is just declaration, it has no definition. – billz Jul 11 '14 at 00:52
  • @billz if inner foo() has no definition. Then what code was executed by the print out statement? –  Jul 11 '14 at 00:53
  • The rules are different for functions than for variables; if you did `int bar;` and then the nested `int bar;`, that is actually two different variables. However there is only one `foo()`. – M.M Jul 11 '14 at 01:05
  • @MattMcNabb I am actually thinking of a way to printing out the two function specifiers to verify this. –  Jul 11 '14 at 01:08
  • 2
    @modeller OK but beware: some common compilers allow an extension `int foo() { return 43; }` as a nested function, and you will then find that the nested `foo` is different to the global `foo` . But this is not part of Standard C++. – M.M Jul 11 '14 at 01:09
  • @MattMcNabb Verified. Indeed the same function. –  Jul 11 '14 at 01:30

2 Answers2

2

This is perfectly fine to redeclare a function like this, we can see this from draft C++ standard in two places, in section 3.1 Declarations and definitions which says:

A declaration (Clause 7) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.[...]

and goes on to say:

A declaration is a definition unless it declares a function without specifying the function’s body [...]

and in section 13.1 Overloadable declarations paragraph 3 which says:

Parameter declarations that differ only in the use of equivalent typedef “types” are equivalent. A typedef is not a separate type, but only a synonym for another type (7.1.3). [ Example:

 typedef int Int;

 void f(int i);
 void f(Int i); // OK: redeclaration of f(int)
 void f(int i) { /* ... */ }
 void f(Int i) { /* ... */ } // error: redefinition of f(int)

—end example ]

Both declarations will refer to the same definition, you are not allowed to redefine the function.

The function declarations of are also allowed to differ by their outermost cv-qualifiers as well.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Good quote from the standard, if only it can mention about nested scopes. Voted up. –  Jul 11 '14 at 01:29
  • @modeller Can you clarify what you mean by nested scope? Matt mentioned nested functions but those are not standard. – Shafik Yaghmour Jul 11 '14 at 01:34
  • Oh I only mean that the nested scope might add complication. E.g. an outer and inner var decl will generate 2 distinct objects. But two nested func decl will now. We are only discussing nested decl but not def so it is OK to put another func decl inside main(). –  Jul 11 '14 at 01:38
2

The inner foo is just another forward deceleration of the same foo(). Consider the following example:

 int foo();
 int foo();

 int main() {
     cout << foo() << endl;
 }

 int foo() { // one definition
    return 42;
 }

This will compile and run and there is no ambiguity because the compiler will replace the use of the same function with the same code.

It is fine to re declare functions.

Fantastic Mr Fox
  • 32,495
  • 27
  • 95
  • 175