使用終結符值來確定 va 列表的結尾

對於任何可變引數函式,該函式必須知道如何解釋變數引數列表。 傳統方法(以 printf 為例)是指定前面的引數數量。但是,這並不總是一個好主意:

/* First argument specifies the number of parameters; the remainder are also int */
extern int sum(int n, ...);

/* But it's far from obvious from the code. */
sum(5, 2, 1, 4, 3, 6)

/* What happens if i.e. one argument is removed later on? */
sum(5, 2, 1, 3, 6)  /* Disaster */

有時,新增顯式終結符會更加健壯,例如 POSIX execlp() 函式。這是計算一系列 double 數字之和的另一個函式:

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

/* Sums args up until the terminator NAN */
double sum (double x, ...) {
  double sum = 0;
  va_list va;

  va_start(va, x);
  for (; !isnan(x); x = va_arg(va, double)) {
    sum += x;
  }
  va_end(va);

  return sum;
}

int main (void) {
  printf("%g\n", sum(5., 2., 1., 4., 3., 6., NAN));
  printf("%g\n", sum(1, 0.5, 0.25, 0.125, 0.0625, 0.03125, NAN));
}

良好的終結者值:

  • 整數(假設全部為正或非負) - 0-1
  • 浮點型別 - NAN
  • 指標型別 - NULL
  • 列舉器型別 - 一些特殊值