Answer: NO
To understand this read the explanation given below:
An example program in C language:
// Example 1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- int var_Global; void main ( ) { var_Global = 5; }
In the above program a global variable var_Global is declared of integer type. This global variable is used in the main ( ) section. When a C language program is executed, the Compiler of C language acquires a calculated amount of memory to execute programming instructions.
C compiler in association with Operating system bifurcate program into three sections and allocate memory accordingly. Program bifurcation is given in Figure 1 below:
C compilers use stack region to maintain memory address allocated to C program. Working of the stack can be understood by taking following example:
// Example 2 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void uderstanding_fun ( ) { int local_variable = 0; local_variable++; }
Code Analysis Understanding_fun: stacktop = stacktop-4; stacktop[0] = 0; stacktop[0]++; stacktop = stacktop+4 return When the execution of the function begins, stacktop points to the top of the stack. Then stacktop is decreased by 4 bytes. These 4 bytes are used by local variables declared in the function. When the function execution ends, stacktop attains the same position which it was before the execution of the function begins. In this code only one variable is used named as local_variable stacktop is decreased by 4 bytes. If other variables were also used then stacktop would have decreased accordingly to store them in memroy.
Compiler converts the C program into the assembly code. Assembly code for the above C program is given below:
//Assembly Code for Example 2 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Understanding_fun: psuh_l %ebp_register mov_l %esp_register, %ebp_register Sub_l $16, %esp_register mov_l $0, -4(%ebp_register) add_l $, -4(%ebp_register) laeve ret
Assembly Code Analysis of Example -1
# function begins with
Understanding_fun:
# store ebp_register on stack. This is done by following assembly code statement:
push_l %ebp_register
When the function execution ends ebp_register attains the value which it was before the execution of the function Understanding_fun begins.
# next stack pointer points to ebp_register.
mov_l %esp, %ebp
# decrease the stack pointer by 4 bytes as the size of the local variable is of integer type. This is done by following assembly code instructions:
sub_l $16, %esp
By decreasing the stack pointer memory space is created to store declared variables inside the function. Now integer variables occupy 4 bytes of memory. But in the assembly code 16 bytes are saved because the C compiler may use this memory if required during function execution.
Next, memory is allocated to declared local_variable and set to 0 by executing following assembly code instruction:
mov_l $0, -4(%ebp)
local_variable is incremented by executing following assembly code instruction: add_l $1. -4(%ebp)
At the end of the execution of the function registered stored to there previous values.
Function Call
An example C language code for function call:
// Example 3 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void stk_fun( ) { int x = 0; x++; } int main ( ) { stk_fun( ); }
Assembly code for example 3:
// Example 3 assembly code -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .text .global stk_fun stk_fun: push_l %ebp_register mov_l %esp_register, %ebp_register sub_l $0, -4(%ebp_register) mov_l $1, -4(%êbp_register) laeve ret .global main main: push_l %ebp_register mov_l %esp_register, %ebp_register call stk_fun pop_l %ebp_register ret
// Code analysis for Assembly Code of example 3 Function of the C language is stored in the text section of the memory occupied by the C compiler. This done by executing following programming instructions: # .text segment begins .text Function stk_fun is exported by following assembly code statement .globl stk_fun Function stk_fun begins:
stk_fun: push_l %ebp_register mov_l %esp_register, %ebp_register sub_l $16, %esp_register mov_l $0, -4(%ebp_register) add_l $1, -4(%ebp) leave ret
Then function stk_fun will be exported by executing following assembly code instructions: .globl stk_fun main function begins by the following assembly code instructions: main: push_l %ebp_register mov_l %esp_register, %ebp_register main function execute the following assembly code to function stk_fun call fun When execution of the function stk_fun ends all assembly language registers are set to default values. popt %ebp_register ret “call” assembly language instruction is used to call functions in C language, when call is made the next instruction address is pushed into the stack. The function in assembly language is kept in the text section denoted by .text. When the execution of the code is completed control is returned back to the main function. This is done by executing the ret statement of the assembly language. ret statement gets the return address from the stack. ret statement pops the address from the stack then goes to that address.
Structure and Compiler generated Assembly language Code
Structures in C language are used to store data of heterogeneous type. Structure contains data members and is accessed using the dot operator. Compiler allocates memory to structure when its object is created. Structure also shares contiguous memory allocation.
Amount of memory allocated to the structure is the sum of the memory allocated to each of the structure members. Since data members are of different data types, the compiler separates them using paddings. Compiler does padding to make access of data members faster.
Compilers use base address of structure to access structure data members.
C language program to declare structure
//Example 4 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #include <stdio.h> struct data_struct { int a; int b; }; void display(); struct data_struct global_data; int main() { struct data_struct local_data; global_data.a = 10; global_data.b = 15; local_data.a = 25; local_data.b = 20; printf("\n"); printf("The value of local variable 'a' in main is: %d", local_data.a); printf("\n"); printf("The value of local variable 'b' in mian is: %d", local_data.b); printf("\n"); display(); return 0; } void display() { printf("\n"); printf("The value of global variable 'a' in display function is: %d", global_data.a); printf("\n"); printf("The value of global variable 'b' in display function is : %d", global_data.b); printf("\n"); }
Output: The value of local variable 'a' in main is: 25 The value of local variable 'b' in mian is: 20 The value of global variable 'a' in display function is: 10 The value of global variable 'b' in display function is : 15
Assembly code for Example 4 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .comm global_data 8,4 .text .global main main: push_l %ebp_register mov_l %esp_register, %ebp_register sub_l $16, %esp_register mov_l $10, global_data mov_l $15, global_data+4 mov_l $25, -8(%ebp_register) mov_l $20, -4(%ebp) mov_l $0, %eax_register Leave ret
Offset of data member “a” and data member “b” of the data_struct structure a ⇒ 0 b ⇒ 4 global _data will access structure members as: global_data.a ⇒ global_data+0 or only global_data global_data.b ⇒ global_data+4 In the same way local data members will be accessed as: local_data.a ⇒ -8(%ebp_register) local_data.b ⇒ -4(%ebp)
Code Analysis of Example 4 In assembly code of example 4 structure data_struct is declared with tag .comm and this is used to specify that data members of structure data_struct will hold memory space in the data section of the total memory space held by the compiler to execute example 4. But assembly code of example 3 begins with .text that specify that example 3 contains a function. Compiler has a definition that variables or data members should be declared in the data section and function should be declared in the code section identified by .text. It is because of this reason that structure can not have function within them
If a function is defined in the structure what will happen
What will happen if function is declared in structure can be understood by following program:
Function within structure
//Example 5 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #include <stdio.h> struct Student_Data { char *student_name; int student_id; int student_age; void add(); }; void add( ) { int a,b; int sum = 0; printf("Input value of a "); scanf("%d", &a); printf("Input value of b"); scanf("%d", &b); sum = a+b; printf("Total Sum is =%d", sum); } int main( ) { struct Student_Data stu; stu.student_name = "Involve"; stu.student_id = 12346; stu.student_age = 300; printf("Name of Student is: %s", stu.student_name); printf("\n Id of Student is: %d", stu.student_id); printf("\n Age of Student is: %d", stu.student_age); return 0; }
Output: main.c:8:10: error: field ‘add’ declared as a function void add(); ^~~
Code Analysis As it can be seen from the code output that the error is field ‘add’ declared as function. Anything declared within a structure is treated as a field that is data members and data members are allocated memory in the data section and in the code section functions are allocated memory out of the total memory allocated to the compiler for the execution of the program.
What will happen if the function is defined in the structure
//Example 6 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #include <stdio.h> struct Student_Data { char *student_name; int student_id; int student_age; void add() { int a,b; int sum = 0; printf("Input value of a "); scanf("%d", &a); printf("Input value of b"); scanf("%d", &b); sum = a+b; printf("Total Sum is =%d", sum); } }; int main() { struct Student_Data stu; stu.student_name = "Involve"; stu.student_id = 12346; stu.student_age = 300; printf("Name of Student is: %s", stu.student_name); printf("\n Id of Student is: %d", stu.student_id); printf("\n Age of Student is: %d", stu.student_age); return 0; }
Output: error: expected ';' at end of declaration list void add() error: expected ';' at end of declaration list void add()
Code Analysis Above code ends with 2 errors. In the first error the compiler considers add function as a list. In the second error compiler considers as a field is exoecting semicolon (;).
Conclusion
From the discussion it is evident that structure cannot have function within it because of two reasons, first, it is allocated memory space in the data section and not in the code section, second, data members declared in structure are considered as a field and field is the term associate with class and C compiler does not have grammar for class so structure does support function either declared or defined in structure.
Leave a Reply