8

I was going through C++11 standard draft a while ago and came across this one (in §8.3.6, p. 204):

void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow

// a parameter with a default argument
void f(int, int);
void f(int, int = 7);
void h() {
    f(3); // OK, calls f(3, 7)
    void f(int = 1, int); // error: does not use default
    // from surrounding scope
}
void m() {
    void f(int, int); // has no defaults
    f(4); // error: wrong number of arguments
    void f(int, int = 5); // OK
    f(4); // OK, calls f(4, 5);
    void f(int, int = 5); // error: cannot redefine, even to
    // same value
}
void n() {
    f(6); // OK, calls f(6, 7)
}

This had to do with default arguments to functions. What struck me was the fact that function declarations appeared at the function scope. Why is that? What is this feature used for?

EML
  • 9,619
  • 6
  • 46
  • 78
Henri Korpela
  • 123
  • 1
  • 5
  • I've used this to declare a function which I know is going to be called within the scope only. – Atul Feb 12 '15 at 06:18
  • The short answer is that it rarely is used. In theory, it could be useful if (for example) you had a variable and a function with the same name. A declaration at an inner scope will hide one at an outer scope. – Jerry Coffin Feb 12 '15 at 06:20
  • https://stackoverflow.com/a/35007616/785194 is the quick answer (for C). – EML May 09 '19 at 10:03

2 Answers2

10

Although I had no idea you can do this, I tested it and it works. I guess you may use it to forward-declare functions defined later, like below:

#include <iostream>

void f()
{
    void g(); // forward declaration
    g();
}

void g()
{
    std::cout << "Hurray!" << std::endl;
}

int main()
{
    f();
}

If you remove the forward declaration, the program won't compile. So in this way you can have some kind of scope-based forward declaration visibility.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Hmm, OK, might become useful some time! :) – Henri Korpela Feb 12 '15 at 06:27
  • 2
    @HenriKorpela I gotta say that I never knew about this, and don't think I'll ever use such a "feature". I'd very much prefer to be able to **define** functions inside other functions, without the need for the common trick of wrapping then as `static` inside a `struct/class`. – vsoftco Feb 12 '15 at 06:28
  • You ever heard of a vexing parse? You can accidentally declare a function rather than an instance. People usually think `Foo f();` declares and calls the default constructor for `f`, but it declares a function instead. – David G Feb 12 '15 at 23:50
  • You said you didn't know you could declare functions inside functions, but you are familiar with the most vexing parse, which is caused by inadvertently declaring a function in a function. – David G Feb 12 '15 at 23:54
  • @0x499602D2 ohhh yes, you're right :) It didn't actually cross my mind, thanks for pointing it out. I misread your comment. – vsoftco Feb 12 '15 at 23:54
  • 1
    https://stackoverflow.com/questions/44943362/reducing-code-duplication-while-defining-a-commutative-operation for useful example of declaration of a function inside another function – Alessandro Teruzzi Jul 06 '17 at 13:53
0

Any function/variable declaration has its visibility and scope. For example, if in class, only class members can see to it. If in function only the function can have visibility to it, after we declare the variable or function.

We generally use data structures within function scope. But compiler's grammar rule is applicable to both, as function in itself has address and hence visibility is applicable to it as well.

Atul
  • 3,778
  • 5
  • 47
  • 87
  • But you can still call the function from any other function that is defined below it, so you just hide it from above (you cannot **define** your function inside other function) – vsoftco Feb 12 '15 at 06:26
  • Yes its essentially about scope. – Atul Feb 12 '15 at 06:28
  • That's what I don't think its true. It's not entirely about scope, as out of scope can still use the function, since you must define the function at the global scope (except of course class members). Only functions declared above it cannot use it. – vsoftco Feb 12 '15 at 06:29
  • If only one could actually define/implement functions in function scopes, there could be more benefits, but sadly, this is not the case. I guess there are good reasons for that, though. – Henri Korpela Feb 12 '15 at 06:31
  • The declaration has scope only after we declare it. This hold true even for variables for example variable valid only in a loop or condition will have visibility to that block only. – Atul Feb 12 '15 at 06:31
  • It's not the same as `{ int x = 2;} cout << x;` Here `x` won't be accessible outside the scope `{...}`, as it left the scope. On the other hand, in `{ int f();} cout << f();` the function `f()` will be accessible, provided it's definition preceded that of the line with `cout`, as its definition must be present in the global scope. – vsoftco Feb 12 '15 at 06:35
  • `f()` will _not_ be accessible unless you declare it outside block. When you define it you actually implicitly declare it as well :) – Atul Feb 12 '15 at 06:37
  • If we forget about function definition then things will be more clear. And anyways, from _compilers_ perspective it doesn't need definition for successful compilation. – Atul Feb 12 '15 at 06:40
  • @Atul ok, technically you're right :) But from your answer one first gets the impression that you can "hide" the function. If you want to use it, you cannot hide it, must define it outside the scope. – vsoftco Feb 12 '15 at 06:40
  • I got it. Use of word 'access' could have made it to feel like "data hiding" in OOP. Well no. I need to rephrase my answer. – Atul Feb 12 '15 at 06:43