Kevin Richards
Kevin Richards

Reputation: 570

Second argument of "va_start"

For the following code:

void fun(char *msg, int n, int m, ...) {
    va_list ptr;
    va_start(ptr, m);  // Question regarding this line

    printf("%d ", va_arg(ptr, int));
}

The function is called as follows:

fun("Hello", 3, 54, 1, 7);

My question is regarding the line commented above. I tried the following three versions of that line:

va_start(ptr, msg);
va_start(ptr, n);
va_start(ptr, m);

In all the three cases I am getting "1" as the output. From what I have read, the second argument of va_start should be the last argument in the parameter list of the function fun(), i.e., va_start(ptr, m); should be the correct call. So why am I getting the same output in all the three cases.

[I ran the program on Ideone, if that is of any consequence.]

Upvotes: 3

Views: 2230

Answers (2)

nascent
nascent

Reputation: 69

First of all the function arguments must be defined conveniently such that it should not contain any of the variable arguments like:

FindMax(int totalNumbers, ...);
va_list ptr;
va_start(ptr, totalNumbers);

Because whatever we write as the second argument in va_start, the va_arg(ptr, int) will start reading from the next argument like such:

int maxnum = va_arg(ptr, int);

Otherwise, we can directly use arguments if it is given in the function declaration because va_arg can only read the variable arguments, not the defined ones.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

The first two calls that you show are undefined behavior according to the C standard; only the call that passes the last named parameter is correct. However, you get good behavior on gcc, because gcc compilers ignore the second parameter of va_start, using a different technique to find the end of the argument list:

The traditional implementation takes just one argument, which is the variable in which to store the argument pointer. The ISO implementation of va_start takes an additional second argument. The user is supposed to write the last named argument of the function here. However, va_start should not use this argument. The way to find the end of the named arguments is with the built-in functions described below {link}.

Upvotes: 11

Related Questions