Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable argument lists in C functions - How to properly iterate through the arg list?

In the following C program i get the warning:

warning #2030: '=' used in a conditional expression.

What exactly is the problem and how do i avoid this? What is the correct way to iterate through the variable arguments?

#include <stdio.h>
#include <stdarg.h>

int Sum(int a, int b, ...)
{
    int arg;
    int Sum = a + b;

    va_list ap;
    va_start(ap, b);

    while(arg = va_arg(ap, int))
    {
        Sum += arg;
    }
    va_end(ap);

    return Sum;
}

int main(int argc, char *argv[])
{
    printf("%d\n", Sum(1, 2, 4, 8));

    return 0;
}
like image 797
Gary Willoughby Avatar asked Jan 02 '10 14:01

Gary Willoughby


1 Answers

What you're doing is idiomatic, if slightly ugly C.

In order to convince the compiler you know what you're doing, though, you could wrap the assignment into an additional set of parentheses:

while((arg = va_arg(ap, int)))

That should take care of the warning.

Update:

adding parenthesis around the assignment doesn't seem to supress the warning in the C99 compiler im using (PellesC). – Gary Willoughby

What, it didn't? Then you need to make the test a little more explicit:

while((arg = va_arg(ap, int)) != 0)

should do the trick. It could also be argued to be slightly more readable.


You're going to ask me what I mean by "slightly ugly."

From working with other languages, I'm used to having a clear separation between testing and modifying. You're doing a test in that while of a value, but at the same time creating a side effect (namely reading in the next argument). As I said, this is considered pretty normal, yea "idiomatic" in C because a lot of C programmers do this; I think there are even examples of similar code in K&R.

By personal preference, I'd probably rewrite this as:

while (1) {
  arg = va_arg(ap, int);
  if (!arg) break;
  ...
}

This clearly separates the assignment from the test, and lets the loop stand alone as a (potentially) infinite loop. Many people would consider my code more ugly; as I said, it's a matter of personal preference.

like image 163
Carl Smotricz Avatar answered Oct 23 '22 03:10

Carl Smotricz