Search code examples
c++function-prototypes

How to call a function whose prototype is scoped inside another function?


to declare a function prototype we declare it outside and on the top which means right before the function definition.

1- I wonder why c++ allows declaring prototypes scoped inside the body of other functions' definitions?

2- How to call a function whose prototype being inside another function's body?

here is an example:

#include "stdafx.h"
#include <iostream>
using namespace std;

void Bar()
{
    cout << "Bar..." << endl;
    void Baz();
}

int main()
{

    void Foo();
    Foo();
    Bar();
    Baz(); // how to call this function?

    cin.get();

    return 0;
}

void Foo()
{
    cout << "Foo..." << endl;
}

void Baz()
{
    cout << "Baz..." << endl;
}

Solution

  • A function prototype inside one function isn't visible inside another, so the code you've written here won't work. However, there's nothing stopping you from providing another function prototype inside of main:

    int main()
    {
    
        void Foo();
        Foo();
        Bar();
    
        void Baz();
        Baz();
    
        cin.get();
    
        return 0;
    }
    

    That having been said, it's pretty unusual to write code like this - if you mean to prototype the function, just do so at global scope. It's rare to see function prototypes defined inside of individual functions and is almost always a mistake or extremely poor coding style.

    C++ allows this for two reasons:

    1. Backwards compatibility. This is legal C code, and historically C++ tried to maintain compatibility with C whenever possible. (There's a lot of legal C code that won't compile in C++, so this isn't a hard-and-fast rule, but it's a good guiding philosophy.)

    2. The "Why Not?" principle. Function prototypes are really just declarations of functions. C++ lets you declare all sorts of objects at different points in time. Allowing function declarations like this inside of a function follows as a special case of allowing for declarations, so explicitly disallowing it would require extra verbage in the spec and potentially might hurt someone in a really bizarre case down the line.

    Arguably, this was a bad decision, because it leads to C++'s Most Vexing Parse. The following line of code, for example, is interpreted as a function prototype:

    std::vector<int> x(); // Oops - it's a function prototype!
    

    Even worse is something like this:

    std::istream input;
    std::vector<int> x(istream_iterator<int>(input), istream_iterator<int>()); // Oops - it's a function prototype!
    

    This was addressed by adding in the new brace initialization syntax:

    std::vector<int> x{}; // Okay, a vector.
    std::vector<int> x{istream_iterator<int>{input}, istream_iterator<int>{}}; // Sure, that's fine too.