TITLE: Var args and base classes


PROBLEM: dkb@calvin.nrtc.northrop.com (David K. Bainbridge)

I am trying to figure out how a derived class can pass a variable
argument list up to it base class constructor.  I searched the FAQ for
some glimpse of hope but found none.  Perhaps the problem can best be
explained with an example.

class A {
    public:
        A (...);
};

class B : public A {
    public:
        B (...);
};

A::A (...)
{
	va_list args;

	va_start (args, NULL);
        (etc ...)
	va_end (args);
}

B::B (...) : A (????)
{
}

Now here is the problem.  What can I put instead of ???? so that the
base class will be automatically initialized with the variable
argument list?


RESPONSE: hf@telematik.informatik.uni-karlsruhe.de (Harald Fuchs), 30 Oct 92

Add a (maybe protected) constructor to your base class, taking a
va_list as an argument:

class A {
protected:
  A (va_list);
public:
  A (...);
};

class B: public A {
public:
  B (...);
};

A::A (va_list args) {
  (etc ...)
}

static va_list args;

B::B (...) : A ((va_start (args, NULL), args)) {
  va_end (args);
}


RESPONSE: kanze@us-es.sel.de (James Kanze), 31 Oct 92

As a result of some discussions in comp.std.c++, I remember a little
more concerning this.  This is *not* legal, although it works on many
compilers.  There is a rule in the ANSI standards that states that the
va_start and va_end must be used in pairs *in* *the* *same* *scope*.
I forget the exact wording in the standard, but the idea was to allow
these macros to define a new scope, by having the va_start open a
block, and the va_end close it.

If you're only concerned with the more frequent systems (Sun's, PC's,
etc.) though, you could probably get away with it.

An alternative (standards conformant) solution might be to create a
helper class, which builds a list from a variable number of
parameters, and then allows accessing the list.  (If any of your class
libraries has a linked list type with an iterator, it would be almost
trivial to do this using this type.)  Of course, you would then have
to use this helper class as parameter to the destructor.  (I've done
this on a number of occasions, and it works pretty well.)


