Local function declaration seems to be permitted in gcc, and I found a discussion on this: Is there any use for local function declarations?
However, my question is: is it allowed by ISO C standard? If it is, how to explain the following phenomenon which makes it puzzling:
int main(void) {
int f(void);
f();
}
void g(void) {
/* g has no idea about f. It seems that the decl is limited within its
* scope */
f();
}
int f(void) {}
while
int main(void) {
int f(void);
f();
}
void f(void); /* error because disagreement with the local declaration (local
declaration goes beyound its scope?) */
void f(void) { /* definition here */ }
According to the C99 standard: function names are in the same naming category. So we shall discuss the scoping mechanism to explain this. But how?
Actually, I'm working on a compiler course project which requires us to implement a simplified version of C compiler. I was trying to deal with this case but got confused.
EDIT: I know it's a common knowledge that C is procedure-oriented and requires function names to be unique. But this local style of declaration stirs clear situation, and it's hard for me to understand its principle/rule.
Both ISO C and C++ permit local function declarations. In each case the scope of the function declaration ends at the end of the local scope. However, the function declaration and its definition have external linkage so they still need to be acceptable to the linker.
In your sample:
int main(void) {
int f(void);
f();
}
void f(void);
void f(void) { }
This code compiles without error, as either C or C++. In C is should link (usually), but in C++ it will not (because of "typesafe linkage"). There will be an unresolved external for int f(void);
.
[If this does not answer your question because of difficulties with your English, please clarify and I'll edit the answer.]
The C standard contains the following. n1570/S6.7.1/7:
The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.
Clearly local function declarations are explicitly permitted.
n1570 S6.2.2/5 on external linkage:
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
So local function declarations have external linkage. This is obvious: if they had internal or no linkage, they could not link to anything.