0
votes

I am trying to pass a variable arguments list of void* elements to a function in C.

  1. How do I do this?

  2. How do I calculate the number of items in the list?

  3. How do I loop through the var-args list and pass each void* item to another function that takes a void* item as its parameter?

This is what I have done, but it is not working.

 void AddValues(List* data, void* args, ...) {

 int len = sizeof (args) / sizeof (*args);


 for(int i=0;i<len;i++){ processItem(args[0]); }

 }

 void processItem(void* item){

 }
1
You can't calculate the length that way. sizeof (args) / sizeof (*args) = sizeof(void*) / sizeof(void) but void has no size. Functions that take varargs lists need to be able to determine the size from some other source: - another parameter (printf uses the number of % in the format string) or a special value (like all the void* pointers point to things and the last one is NULL) So either the first parameter has to be the size or your last void* must have a special sentinel value.Jerry Jeremiah
@gbenroscience Your void* parameter has absolutely nothing to do with the ... for var-args. You cannot deference a void*, and if you could it wouldn’t tell you how many things were pointed to or anything because as far as the compiler is concerned it’s just a pointer to void.Daniel H

1 Answers

2
votes

How do I calculate the number of items in the list?

You can't. It must be provided or derivable.

How do I loop through the var-args list and pass each void item to another function that takes a void* item as its parameter?*

As documented in Variadic Functions,

#include <stdarg.h>

void AddValues(int count, ...) {
   va_list args;
   va_start(args, count);

   for(int i=count; i--; )
      processItem(va_arg(args, void*));

   va_end(args);
}

Example usage:

void* p1 = ...;
void* p2 = ...;
void* p3 = ...;
void* p4 = ...;

AddValues(4, p1, p2, p3, p4);

It depends on what you are doing, but you should probably be using an array instead of variadic parameters.

void AddValues(int count, const void** args) {
   for(int i=count; i--; )
      processItem(*(args++));
}

Example usage:

#define C_ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0]))

void* ptrs[4];
ptrs[0] = ...;
ptrs[1] = ...;
ptrs[2] = ...;
ptrs[3] = ...;

AddValues(C_ARRAY_LEN(ptrs), ptrs);

Or (if the pointers can't be NULL):

void AddValues(const void** args) {
   while (*args != NULL)
      processItem(*(args++));
}

Example usage:

void* ptrs[5];
ptrs[0] = ...;
ptrs[1] = ...;
ptrs[2] = ...;
ptrs[3] = ...;
ptrs[4] = NULL;

AddValues(ptrs);