Importance of function prototype in C
Function prototype tells the compiler about a number of parameters function takes data-types of parameters, and return type of function. By using this information, the compiler cross-checks function parameters and their data type with function definition and function call. If we ignore the function prototype, a program may compile with a warning and may work properly. But sometimes, it will give strange output and it is very hard to find such programming mistakes. Let us see with examples
The above program checks the existence of a file, provided from the command line, if a given file exists, then the program prints “file exists”, otherwise it prints an appropriate error message. Let us provide a filename, which does not exist in a file system, and check the output of the program on x86_64 architecture.
[narendra@/media/partition/GFG]$ ./file_existence hello.c Segmentation fault (core dumped)
Why this program crashed, instead it should show an appropriate error message. This program will work fine on x86 architecture but will crash on x86_64 architecture. Let us see what was wrong with the code. Carefully go through the program, deliberately I haven’t included the prototype of the “strerror()” function. This function returns “pointer to the character”, which will print an error message which depends on errno passed to this function. Note that x86 architecture is an ILP-32 model, which means integer, pointers and long are 32-bit wide, that’s why the program will work correctly on this architecture. But x86_64 is the LP-64 model, which means long and pointers are 64 bit wide. In C language, when we don’t provide a prototype of a function, the compiler assumes that function returns an integer. In our example, we haven’t included the “string.h” header file (strerror’s prototype is declared in this file), that’s why the compiler assumed that function returns an integer. But its return type is a pointer to a character. In x86_64, pointers are 64-bit wide and integers are 32-bits wide, that’s why while returning from a function, the returned address gets truncated (i.e. 32-bit wide address, which is the size of integer on x86_64) which is invalid and when we try to dereference this address, the result is a segmentation fault.
Now include the “string.h” header file and check the output, the program will work correctly.
[narendra@/media/partition/GFG]$ ./file_existence hello.c No such file or directory
Consider one more example.
The above code will work fine on the IA-32 model but will fail on the IA-64 model. The reason for the failure of this code is we haven’t included a prototype of the malloc() function and the returned value is truncated in the IA-64 model.
This article is compiled by Narendra Kangralkar. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.