1

Accidentally I compiled a source similar to this:

//void y(); //optionally declaring y()

void x()
{
  //some code...
  void y();
  //some code...
}

//void y() {/*some code*/} //optionally defining y()

This was compiled with VS 2017 and also two clang versions. None of these compilers complained about this source code – no errors, no warnings. There was a typo in my code – in this example, there should be no void in front of y() and therefore y() was supposed to be called, so it was a rather sneaky bug with no visible consequences while compiling.

I was curious what the compiler was thinking. Trying to debug the code, the void y(); line inside x() was inaccessible, so seems like no actual machine code was produced. I tested this with the void y() {/*somecode*/} function declared above and defined below x() and also with no such function – no difference.

Did the compilers consider this a declaration? if so, how this could be further used when defining a function within a function this way (not speaking about lambdas) is not allowed in C++? I assume that if such a declaration is valid inside a function, it would mostly make sense if one wanted to define a function inside x() as well, otherwise the declaration of y() could be moved outside and above x().

EDIT: Related discussions and explanations:

dolphin
  • 1,192
  • 10
  • 27
  • 1
    It's just a function prototype declaring that `y` is a function that takes no arguments and returns no value. It's odd to put one inside a function, but perfectly legal. And you can have nested function definitions thanks to things like lambdas... – Shawn Jul 21 '19 at 01:35
  • 1
    "Did the compiler(s) consider this a declaration?" Yes. It's just that and nothing more. No code is generated unless you call it. – doug Jul 21 '19 at 01:35
  • Extension to @doug 's comment: And then you better have a definition for the function somewhere or the linker will be quite perturbed. – user4581301 Jul 21 '19 at 01:36
  • I know about lambdas, but this is not related and they require a different syntax. @Shawn: If this is a function prototype, how this can be used further? At doug: how can I call it? what can be called? – dolphin Jul 21 '19 at 01:38
  • You'd call it like any other function? `y();`. – Shawn Jul 21 '19 at 01:39
  • @dolphin If you weren't aware, this syntax goes back to `C`. There is nothing specifically `C++` about it. – PaulMcKenzie Jul 21 '19 at 01:45
  • Possible duplicate of [Why can't I define a function inside another function?](https://stackoverflow.com/questions/29967202/why-cant-i-define-a-function-inside-another-function) – JaMiT Jul 21 '19 at 03:30

1 Answers1

2

I was curious what the compiler was thinking.

Its thinking that you declared a function by the name y that returns void and has an empty argument list. void y(); is a function declaration.

Did the compiler(s) consider this a declaration?

Yes.

if so, how this could be further used when nested functions are not allowed in C++?

You can use a function declaration for example to call it, or to take its address. Like so:

void x()
{
    void y(); // a function declaration

    // now that y has been declared, it can be called:
    y();      // a function call

    // also, it is now possible to take the address:
    void (*fun_ptr)() = y;
}
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Indeed, thanks, this is so rarely used that it seemed awkward to my eyes, and I could not see a use case, or some advantages, for this syntax (usually one declares y() outside of x(), or in a header file that is included first). I was thinking along the lines of: if you insist on declaring a function inside another function, you sure want to define this new function inside as well! – dolphin Jul 21 '19 at 01:55