Lee5 Lee5 - 5 days ago 6
C++ Question

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;
}

Answer

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.
Comments