Posts Tagged c

Erasing Iterators from STL Containers (STL Vector, etc.) in a Loop

for( vector<aType>::iterator it = aVec.begin(); 
      it != aVec.end(); 
      it = (*it).shouldDelete()?aVec.erase(it):it+1){
   // do stuff
}

, , , , , , , , , ,

2 Comments

Using Variadic Functions in C

I don’t really need to write on how to use va_list, va_start, va_end, va_arg because other tutorials or references do a good job of explaining it already… however, here are some notes for wrapping Varadic functions.

Firstly, note the difference between:

void myFc( int arg1, ... )

and the va_list version:

void vmyFc( int arg1, va_list args)

gnu stdc libraries (printf, etc) wrap the va_list versions (vprintf, etc) with Variadic versions (printf, etc) with the following pattern:

int vfunc(int arg1, va_list vargs){
   // do real work
}
int func(int arg1, ...){
   int retval;
   va_list vargs;
   va_start(vargs, arg1);
   retval = vfunc(arg1, vargs); 
   va_end(vargs);
   return retval;
}

When wrapping va_list functions, it is important to consider that va_list is consumed and so in the case where you will be using your va_list for multiple functions, you’ll need to save the original pointer.

GNU C doc for stdarg.h — Note the __va_copy macro.

For example, wrapping the snprintf function:

//to find the length of the string, you pass null and length 0 to the function:
len = vsnprintf(NULL, 0, fmt, vargs);

//do the allocation
str = (char*) malloc(len+1);

//and finally read the string:
vsnprintf(str, len+1, fmt, vargs);

note that we use the va_list version of snprintf (vsnprintf).

the 2nd snprintf may (depending on stdarg implementation) cause a segmentation fault. The correct/safe way of doing it would be to copy vargs and use the copy in each snprintf operation:

#ifdef __va_copy
   __va_copy(save,vargs);
#else
   save = vargs;
#endif
len = vsnpritnf(NULL, 0, fmt, save);

str = (char*) malloc(len+1);

#ifdef __va_copy
   __va_copy(save,vargs);
#else
   save = vargs;
#endif
vsnpritnf(str, len+1, fmt, save);

But as my awesome co-worker Geoff asserts, its always better to keep it simple and perhaps there’s a way to accomplish what you’re trying to do without Variadic functions. Check out my other post.

PST~ this was just a brain dump of what was on my mind as I was coding today… if you find this useful and/or find some info lacking OR just incorrect, leave a comment so I can fix it.

, , , , , , , , , , , , , , , , , , , , ,

1 Comment