How to set the default when no additional arguments are used using va_list in C

I had a problem trying to write a function that has a default value when no additional arguments are given. I tried to determine if a single argument is NULL (as suggested in other answers), but it doesn't seem to work for me.

The actual implementation of this function takes a structure and adds it to the linked list specified in the second argument. If the second argument is not specified, I want it to add it to the default global linked list that was previously defined.

Below is a simpler version using arguments of type int, but the principle of what I want to do is the same:

/* appropriate headers... */ void test(int a, ... ) { int b; va_list args; va_start(args,a); b = va_arg(args,int); if (b == NULL) { // check if no argument is given and set default value b = 0; } // if b != NULL then it should be set to the value of the argument va_end(args); printf("%d %d\n",a,b); } int main() { test(1); test(1,1); return 0; } 

However, this gives the result:

 1 *random memory address* 1 1 

The output I want should have the first line as

 1 0 

If I cannot use this method, anyone has ideas, how can I achieve what I want? Thanks in advance.

+4
source share
3 answers

There is no way to do what you want using va_list .

You can use macros and __VA_ARGS__ to make a particular argument appear last in the argument list as a "terminator". i.e:.

 #define TEST(a, ...) Test(a, __VA_ARGS__, 0) 

Please note that I am using Visual C ++. Other compilers may implement __VA_ARGS__ slightly different way, so you may need to configure the implementation.

+4
source

Your function accepting variable arguments should somehow say when it reaches the end of the variable arguments. This can be by analyzing information from fixed arguments (for example, an argument that tells you how many arguments were passed, or a format string that tells you which arguments should follow), or it could be an explicit sentinel value, such as a null pointer , at the end of the variable arguments.

You seem to want a major miracle; Sorry, but only minor miracles are available.

You can create your interfaces as follows:

 int test1(int x, struct list *list) { ...code to handle adding x to arbitrary list... } int test0(int x) { return test1(x, &global_struct); } 

Then you call test0() when you want to use the default list, and test1() when you want to specify a different list.

Note that test0() so simple that it is a good candidate for defining the C99 inline function.

If you used C ++, you could provide a function with a default argument or an overloaded function (two lists of arguments and implementations, as mentioned above, but with the same name). Of course, even more than in C, the use of global variables is deprecated in C ++.

+2
source

A function should have some way of knowing how many arguments were provided. Your function has no way, so it cannot work. You can create two functions. You may have a separate parameter "number of arguments". You can include another parameter that indirectly tells it how many parameters it has (for example, printf ). But you have to do it somehow.

+1
source

Source: https://habr.com/ru/post/1390756/


All Articles