2

I was reading this question, that is related to mine, and even though the linked question was asking the reasons why such construct is possible in C, the answers did not address the point and discussed about some other problems.
I do not understand what is the benefit of having a function declaration inside another function and I can't even imagine a scenario where it's really useful.
I would like to see an example where inside declaration can bring something that outside can't, or at least, a scenario where it's better, more useful or cleaner.

  • One of the answers to the question you link to claims that it has a use, though I am not convinced. – John Coleman Jan 22 '18 at 16:16
  • See https://stackoverflow.com/questions/957592/functions-inside-functions-in-c – Jonny Schubert Jan 22 '18 at 16:16
  • 1) It is *not* standard C. 2) The same as with local vs global variables - scope limitation. – Eugene Sh. Jan 22 '18 at 16:18
  • @JonnySchubert That question involves nested function *definitions* -- this only involves *declarations*. – John Coleman Jan 22 '18 at 16:18
  • 1
    @EugeneSh., standard C does not permit a function *definition* to appear at block scope, but it certainly does allow a function declaration that is not a definition to appear at such scope. – John Bollinger Jan 22 '18 at 16:25
  • @JohnBollinger Hm. Missed this point. – Eugene Sh. Jan 22 '18 at 16:26
  • @John Coleman: That's right but the question is still related that's why I don't wrote duplicate – Jonny Schubert Jan 22 '18 at 16:46
  • One could ask "Is function declaration inside another function harmful?" To this end a funciton could have an unchariastically have an `#include "xyz.h"` to bring in typedefs, constants and even functions declarations useful here, but not in other functions of the .c file. I see little value in this construct, but little harm. – chux - Reinstate Monica Jan 23 '18 at 01:28

2 Answers2

4

I do not understand what is the benefit of having a function declaration inside another function and I can't even imagine a scenario where it's really useful.

There is a benefit to the standard and its consumers (us): the standard can express the syntax and semantics for declarations a bit more simply, without making special exceptions. The point is not that there is any particular benefit to declaring a function at block scope, but that it is mostly harmless to do so, and allowing it makes the language a little more consistent.

Nevertheless, it is poor style to declare functions at block scope. This makes your code harder to maintain, because if the function signature changes then you need to find and fix occurrences all over the place. That's why it's only mostly harmless.

One answer to the question you linked argues that block-scope function declarations serve to keep the global namespace cleaner, but this is not really true. Although declaring a function only at block scope does mean that declaration is not visible outside that block, there still cannot be more than one external definition of that function anywhere in the program. All references to an external function of that name refer to that one function, so it occupies a slot in the global namespace, whether its identifier is in scope in any particular translation unit or not.

I would like to see an example where inside declaration can bring something that outside can't, or at least, a scenario where it's better, more useful or cleaner.

There is no such example. It is always better and cleaner to declare functions at file scope. Functions with external linkage, moreover, should be declared in header files, and those headers #included into translation units where the function is referenced or defined.

Update: As you can see in the comments to this answer, one could speculate that a block-scope declaration would permit an external function to be called from a translation unit in which the same identifier is declared, with internal linkage, to refer to something else. This sort of scheme could only work if the identifier were declared with external linkage inside a block that precedes any file-scope declaration of the identifier, and declared with internal linkage later, at file scope. But that situation is not allowed: within any given whole translation unit, the same identifier cannot be declared with both internal and external linkage.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    What in the standard prevents `void foo(void) { extern void xxx(void); } static int xxx;`? I was thinking somebody who already has an internal function or object named `xxx` might want to use third-party code that defines an external `xxx`, so limiting the scope of the external `xxx` could let them do that. However, my compiler objects (“redefinition… as different kind of symbol”), and I do not see the reason for that in the standard. – Eric Postpischil Jan 22 '18 at 17:17
  • I'm not sure yet, @EricPostpischil. I looked into that a bit, and my compiler even rejects that scenario when `xxx` is declared in both places as a function, on account of the difference in linkage. But perhaps the compiler is in error. – John Bollinger Jan 22 '18 at 17:31
  • 1
    @EricPostpischil, it looks like that would be [paragraph 6.2.2/7](http://port70.net/~nsz/c/c11/n1570.html#6.2.2p7): "If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined." Note that there is no requirement for overlapping scope there. The error message you got is a little misleading, then, but the behavior *is* undefined. – John Bollinger Jan 22 '18 at 18:10
3

You're right. Declaring a function inside another is never useful, as functions are always linked externally, unlike variables that may have automatic storage duration and block scope.

Due to the layout of executable binaries, a function is always accessible from another in the same binary, so it makes little sense to declare it inside another function, or more precisely, have a function with limited scope.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
iBug
  • 35,554
  • 7
  • 89
  • 134
  • Well it could be somewhat useful. E.g in Pascal nested functions have access to the local variables of the containing function (somewhat like "local global" variables). I'm not sure if the gcc extension allows this too. – Jabberwocky Jan 22 '18 at 17:00
  • 1
    Functions are not always linked externally. Functions declared with `static` have internal linkage (C 2011 [N1570] 6.2.2 3). – Eric Postpischil Jan 22 '18 at 17:08