valkiara
valkiara

Reputation: 9

va_arg always runs 4 times

I am learning stdarg.h in c i am trying to print all arguments passed to function without knowing how many arguments are there but yet i have not come up with solution, during this this happened, no matter what i pass to strtest. It always print 0. 1. 2. 3.

void strtest(char *fmt, ...){
    va_list argp;
    int i = 0;

    va_start(argp, fmt);

    while(va_arg(argp, char*))
        printf("%d\t", i++ );

    va_end(argp);
}

int main(int argc, char *argv[]){
    strtest("s");
    printf("\n");
    return 0;
}

Upvotes: 0

Views: 325

Answers (5)

hennign
hennign

Reputation: 144

If you look at the man page for stdarg, va_arg includes this text

If there is no next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), random errors will occur.

Unless you call strtest with a NULL as the last argument, va_arg will just keep reading until it hits something that makes it stop. Think of what you are doing right now as equivalent to reading an array outside its bounds.

I'm surprised it was running 4 times no matter what though. I would have expected the count to be equal to the number of args you passed to strtest plus 2 or more.

Upvotes: 0

Weather Vane
Weather Vane

Reputation: 34585

Here is an example showing one way to pass an unknown number of arguments.

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

void print (char *first, ...)
{
    va_list argptr;
    char *next;
    va_start (argptr, first);
    next = first;
    while (next) {
        printf ("%s\n", next);
        next = va_arg(argptr, char*);
        }
    va_end (argptr);
}

int main(void)
{
    print("hello","world", NULL);      // NULL as sentinel
    return 0;
}

Program output

hello
world

Perhaps you can adapt this to your needs using int arguments.

Upvotes: 1

Bobby Sacamano
Bobby Sacamano

Reputation: 540

This is the definition of stdarg.h in the ISO 9899 WG14 n1256

The header <stdarg.h> declares a type and defines four macros, for advancing through a list of arguments whose number and types are not known to the called function when it is translated

You have to pass the number of arguments, and possibly the types as well, to the caller. This doesn't have to be done by directly passing the number of arguments, there are other methods such as the one used in printf.

Upvotes: 1

Jens Gustedt
Jens Gustedt

Reputation: 78923

You could pass a sentinel to the function like this

strtest("s", (char*)0);

such that the function can notice that it is at the end of the argument list.

Upvotes: 0

keithmo
keithmo

Reputation: 4943

There's no standard mechanism that will tell you the number of arguments passed to a varargs function. Functions like printf() work because they can determine the number of arguments by examining the format string.

Upvotes: 5

Related Questions