Thread: void before function call

  1. #1
    Registered User
    Join Date
    Oct 2013
    Posts
    24

    void before function call

    Hello Everyone,


    Greeting for the day!


    I have seen this code at some portal and thought to give it a try.


    Code:
    void tom(void)
    {
        static int jerry;
        printf("%d\n", ++jerry);
    }
    
    
    int main()
    {
        void tom(), tom(); // issue
    
    
        tom(), tom();
        return 0;
    }

    The problem catches my attention because of "void" before the function call (highlighting it as //issue). I thought that since function return as void, adding "void" precede function call "tom" would act as casting. At my quick glance, I expected it to print 1 2 3 4 because of the behavior of the static keyword but it seems that my guess was incorrect and it prints just 1 2.




    I further debug this code to get narrow down into details but it seems that line "void tom(), tom();" didn't executed at all and my PC jumps next line skipping these two function.


    I made sure twice that no warning has generated because of "void".


    I replace both "void" as "int" expecting some new warning/error/ result but nothing had happened. Till here I thought that may be compiler is not considering it as function call because of "void" so I changes only the return type of function as int, keeping "void" inside the main to which surprisingly compiler produces error "conflicting type for "tom".




    Can anyone please explain why this behavior?

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,532
    The problem is that void tom() is a function declaration not a cast.

    A good properly configured compiler would be at least warning you about the issues, and probably even emitting an error or two.

    ||=== Build: Debug in chomework (compiler: GNU GCC Compiler) ===|
    main.c||In function ‘tom’:|
    main.c|4|error: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]|
    main.c|4|warning: incompatible implicit declaration of built-in function ‘printf’|
    main.c|4|note: include ‘<stdio.h>’ or provide a declaration of ‘printf’|
    main.c||In function ‘main’:|
    main.c|10|warning: redundant redeclaration of ‘tom’ [-Wredundant-decls]|
    main.c|1|note: previous definition of ‘tom’ was here|
    main.c|10|warning: redundant redeclaration of ‘tom’ [-Wredundant-decls]|
    main.c|1|note: previous definition of ‘tom’ was here|
    ||=== Build failed: 1 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|

  3. #3
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    718
    @shaswat

    The void before the function name means no value is returned from the function. Any other data type before the function name, indicates the type of data returned.

    The data type inside the parentheses indicate the type of the arguments that will be passed to the function. void indicates no data will be passed to the function.

    Code:
    #include <stdio.h>
    
    int foo(void)
    {
       int val = 0;
       // ... Some code here
       // This function returns a value to the calling function
       return val;
    }
    
    void bar(void)
    {
       // ... Some code here
       // This function does not return a value
    }
    
    int main(void)
    {
       int retval = 0;
    
       retval = foo(); // Capture the return value
       bar();          // No value can be returned
    
       return 0;       // main() returns an int to the Operating System
    }
    
    // an alternative for defining main() would be:
    // int main(int argc, char *argv[]) 
    // To allow for the use of command line arguments
    You need to study a good book on the C Programming Language to explain these concepts, and all others you need to learn and use.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,750
    Quote Originally Posted by rstanley View Post
    @shaswat

    The void before the function name means no value is returned from the function. Any other data type before the function name, indicates the type of data returned.

    The data type inside the parentheses indicate the type of the arguments that will be passed to the function. void indicates no data will be passed to the function.

    Code:
    #include <stdio.h>
    
    int foo(void)
    {
       int val = 0;
       // ... Some code here
       // This function returns a value to the calling function
       return val;
    }
    
    void bar(void)
    {
       // ... Some code here
       // This function does not return a value
    }
    
    int main(void)
    {
       int retval = 0;
    
       retval = foo(); // Capture the return value
       bar();          // No value can be returned
    
       return 0;       // main() returns an int to the Operating System
    }
    
    // an alternative for defining main() would be:
    // int main(int argc, char *argv[]) 
    // To allow for the use of command line arguments
    You need to study a good book on the C Programming Language to explain these concepts, and all others you need to learn and use.
    Strictly speaking void main() is quite different to void main(void), as for any other function. The next version of the standard may say that function() is the same as function(void) (it's being discussed) but as it currently stands they're not equivalent

  5. #5
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    718
    Quote Originally Posted by Hodor View Post
    Strictly speaking void main() is quite different to void main(void), as for any other function. The next version of the standard may say that function() is the same as function(void) (it's being discussed) but as it currently stands they're not equivalent
    Strictly speaking, the is NO "void main()"!!! main() should ALWAYS returns an int to the operating system! This is defined by the operating system.

    We cannot make any assumptions about the next "Proposed" Standard, we can only rely on the current version of the C Standard, C18 (Sometimes referred to as C17)

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,532
    Strictly speaking, the is NO "void main()"!!! main() should ALWAYS returns an int to the operating system!
    Actually this is only true if you are talking about a "Hosted environment", in a non-hosted environment the startup function name, number of arguments, and function return type are all implementation defined. So in a frestanding environment void main() could be acceptable.

    5.1.2.1 Freestanding environment
    1 In a freestanding environment (in which C program execution may take place without any
    benefit of an operating system), the name and type of the function called at program
    startup are implementation-defined.
    From C-11 draft "N1548 Committee Draft December 2, 2010 ISO/IEC 9899:201x"

  7. #7
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,750
    Quote Originally Posted by rstanley View Post
    Strictly speaking, the is NO "void main()"!!! main() should ALWAYS returns an int to the operating system! This is defined by the operating system.

    We cannot make any assumptions about the next "Proposed" Standard, we can only rely on the current version of the C Standard, C18 (Sometimes referred to as C17)
    It was late at night and I was merely quoting. What I meant to write is that int function() is not the same as int function(void) in the current and previous version of the standard.

  8. #8
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    Quote Originally Posted by jimblumberg View Post
    The problem is that void tom() is a function declaration not a cast.

    A good properly configured compiler would be at least warning you about the issues, and probably even emitting an error or two.
    @jimblumberg: Thanks, and yeah its my bad that I played with the compiler setting last night and didn't change it at all.

  9. #9
    Registered User
    Join Date
    Nov 2018
    Location
    Amberg in upper palatinate, Bavaria
    Posts
    45
    Hallo shaswat!

    This way was one of the elder standards of c
    Code:
    // Forward declaration of a function
    #include <stdio.h>
    
    void tom(void)
    {
        static int jerry;
        printf("%d\n", ++jerry);
    }
     
     
    int main()
    {
        // void tom(), tom();   it is in modern standards obsolete
    
     
        tom(),
        tom();
        return 0;
    }
    When you work with bigger source code it is useful to split the code in
    more files. I think one of the steps to go to this solution is the second way.
    example:
    Code:
    #include <stdio.h>
    
    void tom(void);  // declaration
     
    int main()
    {
        // void tom(), tom();   it is in modern standards obsolete
    
     
        tom(),
        tom();
        return 0;
    }
    //definition
    void tom(void)
    {
        static int jerry;
        printf("%d\n", ++jerry);
    }
    elder way for a definition of a function:
    Code:
    /*
     *    char *
     *    mid (char *dest, char *str, int pos, int n)
     *  
     *
     *    This function works very much like the BASIC function MID$.
     *    It returns a pointer to a character stringing containing n
     *    characters (null padded if needed) from str starting from position
     *    pos (remember:    since C is zero based, the first position is
     *    postion 0, not position 1).  The new string (dest) is assumed
     *    to be large enough to hold the result.    Not also the external
     *    declaration of strncpy.  This is needed for Lattice C large
     *      model copilation to work (since int's and char *'s are not the
     *    same size in that memory model).
     */
    
    char *mid (dest, str, pos, n)
    register char *dest, *str;
    register int pos, n;
    {
        extern char *strncpy ();
    
                        /* Do a strncpy () to fill
                           the new string with the
                           proper characters */
        new_string = strncpy (dest, &str[pos], n);
    
                        /* Return the pointer to the result */
        return (dest);
    
    } /* mid */
    This example was written 1986 , May 25th

    modern syntax:
    Code:
    char *mid (char *dest, char *str, int pos, int n)
    {
        extern char *strncpy ();
    
                        /* Do a strncpy () to fill
                           the new string with the
                           proper characters */
        new_string = strncpy (dest, &str[pos], n);
    
                        /* Return the pointer to the result */
        return (dest);
    
    } /* mid */
    The keyword 'register' is also obsolete.

  10. #10
    Registered User
    Join Date
    Oct 2013
    Posts
    24
    Many thanks to all the res-ponder and @rusyoldguy thank you for these details.
    and correct me if I am wrong about the removal of keyword "register" is because modern CPU itself capable to do that automatically. Right?

    Quote Originally Posted by rusyoldguy View Post
    Hallo shaswat!

    This way was one of the elder standards of c
    Code:
    // Forward declaration of a function
    #include <stdio.h>
    
    void tom(void)
    {
        static int jerry;
        printf("%d\n", ++jerry);
    }
     
     
    int main()
    {
        // void tom(), tom();   it is in modern standards obsolete
    
     
        tom(),
        tom();
        return 0;
    }
    When you work with bigger source code it is useful to split the code in
    more files. I think one of the steps to go to this solution is the second way.
    example:
    Code:
    #include <stdio.h>
    
    void tom(void);  // declaration
     
    int main()
    {
        // void tom(), tom();   it is in modern standards obsolete
    
     
        tom(),
        tom();
        return 0;
    }
    //definition
    void tom(void)
    {
        static int jerry;
        printf("%d\n", ++jerry);
    }
    elder way for a definition of a function:
    Code:
    /*
     *    char *
     *    mid (char *dest, char *str, int pos, int n)
     *  
     *
     *    This function works very much like the BASIC function MID$.
     *    It returns a pointer to a character stringing containing n
     *    characters (null padded if needed) from str starting from position
     *    pos (remember:    since C is zero based, the first position is
     *    postion 0, not position 1).  The new string (dest) is assumed
     *    to be large enough to hold the result.    Not also the external
     *    declaration of strncpy.  This is needed for Lattice C large
     *      model copilation to work (since int's and char *'s are not the
     *    same size in that memory model).
     */
    
    char *mid (dest, str, pos, n)
    register char *dest, *str;
    register int pos, n;
    {
        extern char *strncpy ();
    
                        /* Do a strncpy () to fill
                           the new string with the
                           proper characters */
        new_string = strncpy (dest, &str[pos], n);
    
                        /* Return the pointer to the result */
        return (dest);
    
    } /* mid */
    This example was written 1986 , May 25th

    modern syntax:
    Code:
    char *mid (char *dest, char *str, int pos, int n)
    {
        extern char *strncpy ();
    
                        /* Do a strncpy () to fill
                           the new string with the
                           proper characters */
        new_string = strncpy (dest, &str[pos], n);
    
                        /* Return the pointer to the result */
        return (dest);
    
    } /* mid */
    The keyword 'register' is also obsolete.

  11. #11
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    716
    Quote Originally Posted by shaswat View Post
    Many thanks to all the res-ponder and @rusyoldguy thank you for these details.
    and correct me if I am wrong about the removal of keyword "register" is because modern CPU itself capable to do that automatically. Right?
    Replace "CPU" with "compiler" and you'd be correct. The "register" keyword is still recognized but doesn't have much (if any) effect anymore with modern optimizing compilers (they know which variables to leave in registers better than a human does, in most cases). The only significant effect the "register" keyword has (ever since the keyword first existed) is that it makes taking the address of a register variable illegal.

    (I could be wrong, but I don't think it was ever legal to declare function parameters with "register" in an old-style function definition, since a caller won't know to put the arguments in registers.)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. difference between void and static void function
    By mahaju in forum C++ Programming
    Replies: 7
    Last Post: 12-27-2011, 04:02 AM
  2. void display record and other funcntion to call result
    By 16800960 in forum C++ Programming
    Replies: 0
    Last Post: 06-03-2010, 09:15 PM
  3. Now that's what I call a void!
    By Salem in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 08-31-2007, 09:21 AM
  4. Passing a variable in void to another void function
    By stevedawg85 in forum C++ Programming
    Replies: 5
    Last Post: 05-05-2006, 06:17 PM
  5. Void call by reference function
    By TheSki in forum C++ Programming
    Replies: 2
    Last Post: 10-29-2001, 09:37 PM

Tags for this Thread