The scope of a function defined within another function

What happens if a function is defined in another function? What is the difference between Code 1 and Code 2?

CODE 1:

#include<stdio.h>

void m();

void main()
{
    m();
    void m()
    {
        printf("hi");
    }
}

      


CODE 2:

#include <stdio.h>

void m();

void main()
{
    void m()
    {
        printf("hi");
    }
     m();
}

      


When I compiled code 1 in the gcc compiler, I got a bind error. But when I compiled code 2 , I didn't get any errors. I got the output "hello" . I want to know how the compilation is done when we write the definition of a function to another function. I know that when we write function definitions not inside another function, wherever the function definition is, we will not get any error when calling that function. for example see below code:


CODE 3:

#include <stdio.h>
void m();
void main()
{
    m();
}

void m()
{
    printf("hi");
} 

      


In code 3 , although I called the function before the definition, it didn't find any error and I got the output. Why doesn't this happen with code 1 .

+3


source to share


6 answers


Neither C nor C ++ allows you to define a function inside another function. It looks like you are using a special language extension of the GCC compiler that allows you to define local functions inside other functions.

In the first program function, m is declared in the file area. Therefore, its definition will be searched by the compiler in the file area. When the function is called inside the main one, only this content-area declaration is visible. However, the compiler did not find the scope definition of its file, so it gave an error.



The second program also has a declaration for the function m in the file area. However, inside the main function function, there is another function declaration m that has block scope and hides the file scope declaration. Note that a definition is also a declaration. Thus, the call to m refers to the function m, which is declared inside main and has block scope. The compiler has a function definition and can call it.

in the third program, which conforms to the C standard inside the main one, the call to m refers to the function m declared in the file area, and in that area there is the definition of that function. Therefore, no problems arise.

+2


source


You cannot define functions within a function. It is not permitted in C

and therefore will not compile. Code snippets 1 and 2 are invalid, and only snippet 3 is valid ANSI C

.

Why code 1 doesn't compile, but code 2 compiles well in gcc
Code 2 compiles under gcc because of the GNU compiler extension extension . You must declare a function before using this extension for the first time to work.



Then why code 3 compiles
In Snippet 3 you declare a function before first use, which is enough for the compiler to place the required code. Linking requires the required reference to the definition code. There is no need for a linker regarding the placement of the definition (in the ISO C specifications), the function definition is allowed to be represented even in a separate compilation unit.

+2


source


It's a scale issue. In your CODE 1 example, the m function is only visible in the main function. So the function header you put before the main one (void m ();) expects a global function m and doesn't find it, so you have a link error. In code example 2, function m is found because it was written before the call, your global function m is still missing, but not used => you have no communication error. In your example code 3, your m function is global and then found as expected with the command header => no error

+1


source


In Code 3, although I called the function before the definition, it did not find any errors and I got the output. Why doesn't this happen with code 1?

Code 3 conforms to the C code standard. A function with an external link can be called wherever the declaration is visible (provided that the definition exists somewhere in the program, it does not have to be in the same file).

When I compiled code 1 in the gcc compiler, I got a bind error.

Nested functions are a GCC extension :

A nested function always has no binding. Declaring one with external or static is erroneous. If you need to declare a nested function before you define it, use auto (which is otherwise pointless for function declarations).

An m

external declaration (file scope declaration void m();

) is displayed at the time of the call . Since there is no external definition in this source file, gcc

it assumes that it is in a different translation unit, and as a result, the linker does not find it. According to the cited documentation, a valid version could be

#include <stdio.h>

int main(void)
{
    auto void m(); /* Hides the outer declaration. */
    m(); /* Refers to the nested function, not to an external one now. */
    void m()
    {
        printf("hi");
    }
}

      

But when I compiled code 2, I didn't get any errors. I got the output "hello".

At the point where it is called m

, the nested function is visible, hiding the scope declaration. A content-scope declaration (a function declaration with an external link) is never used, so the linker does not try to resolve the call.


A conforming implementation can accept the declaration main

as a return function void

, but it doesn't have to. Old (or K & R-style) declarations and definitions are deprecated in C89, C99 and C11, so it is better to use

int main(void);
void m(void);

      

+1


source


Check below link: Nested Function in C

C does not support nested functions, so your code snippets 1 and 2 are not allowed, although you can see that code snippet 2 works because you have a function call after you define the function.

The only piece allowed Code 3

, the rest should not be done in C.

GCC specific extensions: https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

0


source


You don't compile your code as a C standard. GCC is tricky because it has crappy non-standard settings by default. To use GCC as a proper C compiler, you must do gcc -std=c11 -pedantic-errors

where c11 is the preferred standard (switch to c99 if you have an older version of GCC installed). While you're at it, make sure all warnings are on too:

gcc -std=c99 -pedantic-errors -Wall -Wextra

Now that the compiler is configured as a C compiler, we get the following errors:

CODE1 and CODE2:

  • error: The return type of 'main' is not 'int' [-Wmain].

    This error occurs because when GCC is configured as a C compiler, it does not provide an implementation-defined way to specify the main one. You must change main to int main (void)

    .

  • error: ISO C disallows nested functions [-Wpedantic]

    This error occurs because nested functions are not allowed by the C standard. You left with it earlier because you had a non-standard compiler with GCC.

-1


source







All Articles