C library - va_copy() macro



The C stdarg library va_copy() macro is used to copy the state of a va_list variable (src) to another (dest) va_list variable.

The va_end should be called on 'dest' before the function returns or before 'dest' is re-initialized with va_start or va_copy.

This macro is useful when in the same function we have to iterate over the same list of arguments more than once.

Syntax

Following is the C library syntax of the va_copy() macro −

void va_copy( va_list dest, va_list src )

Parameters

This macro accepts a following parameters −

  • dest − It represents an instance of the va_list variable that will received copy of the state.

  • src − It represent the source va_list variable to be copied.

Return Value

This macro does not returns any value.

Example 1: Calculate the sum and average

The following is the basic c example that demonstrate the use of va_copy().

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

void sum_and_average(int count, ...) {
   va_list args, args_copy;
   int sum = 0;

   // Initialize the va_list
   va_start(args, count);

   // Make a copy of the va_list
   va_copy(args_copy, args);

   // Calculate the sum using the original va_list
   for (int i = 0; i < count; i++) {
       sum += va_arg(args, int);
   }
   printf("Sum: %d\n", sum);

   // Calculate the average using the copied va_list
   double average = 0.0;
   if (count > 0) {
      for (int i = 0; i < count; i++) {
         average += va_arg(args_copy, int);
      }
      average = average/count;
   }
   printf("Average: %.2f\n", average);

   // Clean up both va_list variables
   va_end(args);
   va_end(args_copy);
}
int main() {
   printf("Calculating for 3 numbers:\n");
   sum_and_average(3, 10, 20, 30);

   printf("\nCalculating for 5 numbers:\n");
   sum_and_average(5, 1, 2, 3, 4, 5);

   return 0;
}

Output

Following is the output −

Calculating for 3 numbers:
Sum: 60
Average: 20.00

Calculating for 5 numbers:
Sum: 15
Average: 3.00

Example 2: Calculate standard deviation

The following c example uses the va_copy() to copy the 'src' va_list to 'dest' and compute the standard deviation.

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

double ComputeMean(int count, ...) {
   va_list args1, args2;
   va_start(args1, count);
   // Make a copy of args1
   va_copy(args2, args1);

   double sum = 0;
   for (int i = 0; i < count; ++i) {
      double num = va_arg(args1, double);
      sum = sum + num;
   }
   va_end(args1);

   double mean = sum / count;

   // calculate standard deviation
   // use the copied va_list (args2)
   double sum_sq_diff = 0;
   for (int i = 0; i < count; ++i) {
      double num = va_arg(args2, double);
      sum_sq_diff += (num - mean) * (num - mean);
   }
   va_end(args2);

   return sqrt(sum_sq_diff / count);
}
int main() {
   printf("Standard deviation: %lf", ComputeMean(4, 1.0, 2.0, 3.0, 4.0));
   return 0;
}

Output

Following is the output −

Standard deviation: 1.118034
Advertisements