Search code examples
cfunctionargumentsparameter-passingvoid

Why a function with no arguments works, but a function with void as argument doesn't?


In the below codes I am calculating PI with a function external to main(). The only difference between the two is:

  • 1st code. I am not passing any arguments: void calculate_pi ();
  • 2nd code. I am explicitly saying there are no arguments to pass: calculate_pi (void);.

I would have thought the second one is better, but doesn't seem to be the case. Why is this? Thank you!

1st Code:

#include <stdio.h>
#include <stdlib.h>

void calculate_pi ();

int main(void)
{

    calculate_pi ();

    return 0;
}

void calculate_pi ()
{
    int i, signo;
    double pi_approx = 1, pi_final;

    for (i = 1; i < 1000000; ++i)
        {
            signo = (i%2) ? -1 : 1;
            pi_approx = pi_approx + (float) signo / (2*i+1);
        }

    pi_final = pi_approx * 4;
    printf("%.10f\n", pi_final);
}

2nd Code:

#include <stdio.h>
#include <stdlib.h>

void calculate_pi (void);

int main(void)
{

    calculate_pi (void);

    return 0;
}

void calculate_pi (void)
{
    int i, signo;
    double pi_approx = 1, pi_final;

    for (i = 1; i < 1000000; ++i)
        {
            signo = (i%2) ? -1 : 1;
            pi_approx = pi_approx + (float) signo / (2*i+1);
        }

    pi_final = pi_approx * 4;
    printf("%.10f\n", pi_final);
}

Solution

  • Declaring a function with an empty parameter list, as in void calculate_pi();, is an old C syntax that did not specify the parameter types. It should be avoided in new code. Preferably, functions are declared with parameter lists, such as int foo(char *x);. The new syntax provides better type information and allows compiles to check argument types and provide useful warning and error messages.

    Because C used () to declare functions without a specification of parameter types, a different syntax was needed to specify that a function had no parameters. Using (void) was adopted as a special case to indicate this, per C 2018 6.7.6.3 10:

    The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.

    Thus, declaring void calculate_pi(void); does not say that calculate_pi accepts a void parameter; it says that calculate_pi does not have any parameters. This is the preferred way to declare a function that has no parameters.

    Since the function accepts no parameters, it should be called with no parameters, using calculate_pi().

    calculate_pi(void) is not a valid C expression. A function argument must be a value, but void is a type, and the type void cannot appear as a function argument. So the preferred code in modern C is to declare the function to take no arguments:

    void calculate_pi(void);
    

    and call it with no arguments:

    calculate_pi();