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;
}
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:
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.)
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.