3

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.]

3
  • 3
    If I had to guess, the other two are undefined behaviour. Commented Jul 18, 2014 at 12:24
  • Seems like the most relevant text is The parameter parmN is the identifier of the rightmost parameter in the variable parameter list of the function definition (the one just before the ...). This is the same in C and C++. I would think not following that is undefined behaviour. Commented Jul 18, 2014 at 12:29
  • I would assume that your particular implementation of va_start doesn't really need the second parameter to do its job and as such just ignores it and always does the right thing. But it is of course strictly speaking undefined behaviour to call it with anything else but the last parameter. Commented Jul 18, 2014 at 12:34

2 Answers 2

12

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}.

Sign up to request clarification or add additional context in comments.

1 Comment

@Deduplicator Yes, you are right - I meant the first two. I made an edit, thanks!
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.