Why main() should not have void as return type?

Discussion in 'C' started by poornaMoksha, Nov 17, 2011.

  1. The motivation behind writing this article came from the fact that there are still many books/tutorials/softwares etc where I have seen 'void main' being used instead of 'int main'. Still most of the C/C++ newbies are taught to start practice coding with 'void main'. Even I started practicing C in high school with 'void main' but I think that was some 10 yrs back and was mostly due to lack of awareness. But, now tutors/mentors/teachers should understand the fact that using 'void main()' instead of 'int main()' is a wrong practice.

    Here in this short article, I'll take a small example to let you know why its a wrong practice to use void main().

    Whats wrong in it?



    Well, there could be three quick answers to this question :
    1. The ANSI standard says that the main() function should be declared with return type 'int'.
    2. The start-up functions that call main() do expect that the return value of main() be pushed onto stack. Which if not done may cause problems like stack corruption in the programs exit sequence.
    3. Returning no value to the invocation environment that expects a return value may cause some weird problems especially when you run your program from some script that checks the return vale of your program
    When you ask people (who have been using void main() or have been teaching others to use it) to comment on the above three points, most of them say :

    "I don't know but some how it works for me and as long as it works I don't care about all this".

    Well, they are actually correct. Unless they get to see any problem by using void main(), why do they think over it?

    Lets prove it



    Lets take the point(3) above and try to prove that its actually dangerous to use void main() instead of int main().

    The proof requires :
    1. The code that defines main() [easy, as every program has main defined]
    2. The code that calls main() [difficult, as this code is usually hidden]
    3. A shell script that calls our program [not difficult]
    If we see the above point(2), we will find that its actually difficult to show the code that is responsible for triggering the main() function. So we need to rethink and see how to prove our point.

    Well, after a bit of thought It came to my mind that we can actually take a dummy function 'func()' in our program that is defined in a separate file while declared and called from a separate file. So the scenario will be set just as in case of the function main().

    Fine, looks good enough. Lets look at the code :

    Code:
    #ifndef TEST_H_INCLUDED 
     #include"test.h" 
     #endif 
      
     extern int func(); 
      
     int main(void) 
     { 
         int ret = func(); 
         printf("\n Executed!!! with ret[%d] \n", ret); 
         return ret; 
     }
    In the above code, treat func() as if its was main().
    We have declared function func() as extern.

    NOTE : This file can be thought of as a file that contains startup routine that calls main().

    Code:
    #ifndef TEST_H_INCLUDED 
     #include"test.h" 
     #endif 
      
     void func() 
     { 
         printf("\n Inside func()\n"); 
     }
    The code above is where we have actually defined func(). Take a look, we declared func() as returning int earlier but defined here as returning void.

    NOTE: This file can be thought of as any normal file where we define main() as returning void().

    Code:
    #define TEST_H_INCLUDED 
     #include<stdio.h>
    Also, we have the above header.

    Compile the above code using :

    Code:
    gcc -Wall test.c test1.c -o test
    Also, lets run the program :

    Code:
    ~/practice $ ./test 
      
      Inside func() 
      
      Executed!!! with ret[16]
    Wohhooo....A magical value 16 is returned by the function func(). Where does this value came from? Well, it could well be garbage in 'ret' as this variable does not receive any value from the call to func().

    Now, lets see the script that uses the executable prepared out of all the above code :
    Code:
    #!/bin/bash 
     ./test 
     if [ $? -eq 0 ] ; then 
             echo "SCRIPT :: Program ran successfully" 
     else 
             echo "SCRIPT :: Program failure" 
     fi
    The script above runs the executable and then checks the value returned by the executable to the environment.

    Note that the return value of the function func() is used as the final return value to the environment. Since the definition of func() returns nothing, so lets see what happens when the script is run :

    Code:
    $ ./script.sh  
      
      Inside func() 
      
      Executed!!! with ret[16]  
     SCRIPT :: Program failure
    EXPECTED!!!...The script has gone into the failure logic based on the program's return value despite of the fact that our program executed successfully.

    Well folks, this is what could happen if we will use the return type of main() as void.

    Conclusion



    To conclude, this article contains a practical example of why main() should not be declared as void. Hope this helps those people understand the concept those who are still using void main().

    Stay tuned for more!!!
     
  2. archanababu

    archanababu Banned

    Joined:
    Oct 27, 2011
    Messages:
    12
    Likes Received:
    0
    Trophy Points:
    0
    By reading ur article i got an exact idea about the backbone of our program 'main()'. Also got an information about how it can be applied.
     
  3. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    I always try my articles to be practical and informative. Thanks for the motivation!!!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice