Topic: Ellipsis with no "the one just before the" parameter


Author: brangdon@cix.co.uk (Dave Harris)
Date: Tue, 3 Sep 2002 17:00:07 +0000 (UTC)
Raw View
Allan_W@my-dejanews.com (Allan W) wrote (abridged):
> As someone else proposed, we're using a global variable to indicate how
> many arguments we plan to pass. But surely this is inferior to passing
> the number of meaningful arguments as the first argument, which puts us
> back into the previous case.
>
> If someone has a NON-contrived case of a function with ellipsis not
> wanting an initial argument, please post it.

Maybe some situation where both caller and callee both know the number of
arguments at compile-time, but some intermediary doesn't. This is
contrived for illustration...

    typedef void Callee( va_list );

    class Intermediary {
        Callee *pCallee;
    public:
     Intermediary( Callee *pCallee ) : pCallee(pCallee) {
     }

        void call( ... ) {
            va_list args;
            va_start( args, 0 );
            (*pCallee)( args );
            va_end( args );
        }
    };

    void Callee0( va_list ) {
        cout << "Look, no args!";
    }

    void Callee1( va_list args ) {
        int arg = va_arg(args,int);
        cout << "An int: " << arg;
    }

    void caller() {
        Intermediary zero( &Handler0 );
        Intermediary one( &Handler1 );
        zero.call();
        one.call( 42 );
    }

In practice the intermediary would have some purpose, such as message
routing, multi-thread locking, performance measurement or whatever.

I've not tried to compile this but, typos aside, it should work and be
well-defined. It is horribly vulnerable to programmer error. However, it's
hard to make a fully type-checked version without losing genericity
(especially on the number of arguments), efficiency or convenience.

I'd rather have a template mechanism for forwarding arbitrary arguments.
And/or a way to have:

        void Intermediary::call( ... ) {
            (*pCallee)( ... );
        }

do the obvious thing.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: schd@mra.man.de (Dietmar Schindler)
Date: Tue, 3 Sep 2002 17:05:09 +0000 (UTC)
Raw View
Allan W wrote:
> "Tzvetan Mikov" <ceco@jupiter.com> wrote
> > Anyway, it seems to me that implementing va_start( ap, 0 ) would require
> > compiler support in cases where va_start( ap, arg ) does not (if parameters
> > are always in stack, va_start needs just to take the address of arg).
>
> Consider that phrase "compiler support." In what way would the compiler
> support the va_arg macro? Would it have to push the number of arguments
> onto the stack? If so, you've just changed the calling convention for
> ALL functions that use the ellipsis... meaning that libraries for the
> next version of the compiler have to be incompatible with libraries for
> the old version!
>
> If the compiler had to help in some other way, what would it be?

Consider this plain implementation of va_start:

#define va_start(__list,__parmN) __list = (char *) ((char *)(&__parmN) \
 + sizeof(__parmN))

With va_start( ap, arg ), no "compiler support" is required in the sense
that only standard constructs and behaviour are utilized.
With va_start( ap, 0 ), the compiler would have to special-case the
expression (&0) in the va_start macro and evaluate this as the address
of the first function parameter minus sizeof 0 to support it.

Sadly, the standard didn't allow the ellipses as an rvalue similar to an
array name, what would have made possible the following:

#define va_start(__list) __list = (char *) ...

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: iddw@hotmail.com (Dave Hansen)
Date: Wed, 4 Sep 2002 18:47:21 +0000 (UTC)
Raw View
On 31 Aug 2002 03:55:05 GMT, Andreas Schwab <schwab@suse.de> wrote:

>iddw@hotmail.com (Dave Hansen) writes:
>
>|> On 28 Aug 2002 20:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
>|> wrote:
>|>
[...]
>|> >  void dosomethingonthelistofintegers(...)
>|> >  {
[...]
>|> >      nextinteger = va_arg(arglist, int);
>|>
>|> My question is "what is nextinteger if the call was
>|> "dosomethingonthelistofintegers();"?
>
>It's UB, just like dosomethingonthelistofintegers(42).

So, following my argument to the end:

   1) The only differences between "fn(...)" vs. "fn(type p1, ...)"
      are that the function can be called with no parameters,
      or the first parameter can have an unspecified type.

   2) Invoking va_arg on a non-existant paramter result in UB. (as
      stated above).

   3) Presumably, invoking va_arg with a type that does not match
      the first parameter also results in UB.

How, then, do we take advantage af the new capabilities provided by
"fn(...)"?

A new varargs interface that permits the function to determine if any
parameters (or perhaps the parameter count) and/or the type of the
first parameter (and perhaps the rest as well) could be defined.  But
I doubt it's worth it.

Regards,

                               -=Dave
--
Change is inevitable, progress is not.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Andreas Schwab <schwab@suse.de>
Date: 31 Aug 2002 03:55:05 GMT
Raw View
iddw@hotmail.com (Dave Hansen) writes:

|> On 28 Aug 2002 20:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
|> wrote:
|>
|> >Yes, they will misbehave if one passes a wrong argument.  So, it
|> >is the same way with fprintf.  Needs to be documented.
|> >
|> >Let me illustrate:
|> >
|> >  void dosomethingonthelistofintegers(...)
|> >  {
|> >    int nextinteger;
|> >    va_list arglist;
|> >
|> >    va_start(arglist, 0); // special case -- not in Standard
|> >
|> >    do
|> >    {
|> >      nextinteger = va_arg(arglist, int);
|>
|> My question is "what is nextinteger if the call was
|> "dosomethingonthelistofintegers();"?

It's UB, just like dosomethingonthelistofintegers(42).

Andreas.

--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 N   rnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.de (James Kanze)
Date: 31 Aug 2002 03:55:08 GMT
Raw View
"Victor Bazarov" <vAbazarov@dAnai.com> wrote in message
news:<umplcsst76tnd9@corp.supernews.com>...

> If a function is declared precisely as

>     <return_type> foo(...);

> it is rather difficult to begin enumerating unnamed parameters because
> the 'va_start' macro requires the parameter right before the ellipsis.

> It may not be truly useful, and in the light of existence of
> overloading in C++, the ellipsis were probably adopted only for
> compatibility with C,

Actually, C adopted the ellipsis (and function prototypes in general)
from C++.

> but I am curious (and the question has probably come up before, so
> feel free to point me to an older discussion if it's available), could
> it be possible to define 'va_start' so that passing, say, 0, or the
> function name itself, would mean that there is no parameter before it,
> just start from the beginning?

The traditional definitions, using only macros, require a named
parameter.

> I have not written a compiler, so, unfortunately I don't know how
> difficult that might be.

It shouldn't be difficult.  But historical considerations meant that
there was a desire that these could be implemented as pure macros,
without direct compiler support.  And in C++, I suspect that they are
only supported for reasons of backwards compatibility and C
compatibility anyway; there are almost always better ways of solving the
problem that using variable args.

--
James Kanze                           mailto:jkanze@caicheuvreux.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Jens Kilian <Jens_Kilian@agilent.com>
Date: 31 Aug 2002 03:55:18 GMT
Raw View
"Victor Bazarov" <vAbazarov@dAnai.com> writes:
> Let me illustrate:
>
>   void dosomethingonthelistofintegers(...)
>   {
>     int nextinteger;
>     va_list arglist;
>
>     va_start(arglist, 0); // special case -- not in Standard

Just unroll the first item on your argument list; when you use a special
value like 0 to terminate it, there *must* be at least one:

  void dosomethingonthelistofintegers(int nextinteger, ...)
  {
    va_list arglist;

    va_start(arglist, nextinteger);  // standard compliant

    do {
      munge(nextinteger);
      ...
      nextinteger = va_arg(arglist, int);
      ...
    } while (...);
  }

HTH,
 Jens.
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Attila Feher <Attila.Feher@lmf.ericsson.se>
Date: 31 Aug 2002 03:55:22 GMT
Raw View
Victor Bazarov wrote:
>
> Hello,
>
> If a function is declared precisely as
>
>     <return_type> foo(...);
>
> it is rather difficult to begin enumerating unnamed parameters
> because the 'va_start' macro requires the parameter right before
> the ellipsis.
[SNIP]

See the Stroustrup article (C and C++ compatibility) on CUJ.  I believe
there was a very good reason why C required at least one argument be
present before the ...

Attila

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Fri, 30 Aug 2002 23:04:11 CST
Raw View
> > Victor Bazarov <vAbazarov@dAnai.com> wrote:
> > >    <return_type> foo(...);
> > >the 'va_start' macro requires the parameter right before
> > >the ellipsis.

> "Dave Hansen" <iddw@hotmail.com> wrote
> > Consider the implementation of foo.  How do you get the first
> > parameter if you don't know what type it is, or if it even exists?

"Tzvetan Mikov" <ceco@jupiter.com> wrote
> One can never know what their types are or even whether there are any
> variable arguments at all, but it is assumed that some convention is being
> followed (e.g. the format convention of printf/scanf).
> The convention could be, for example, that the function takes a variable,
> but greater than 0, number of arguments and the last one is 0.

But this was Dave Hansen's point. If "the last one is 0," then there
must be a first one!

  void print (int first, ...)
> {
>   int arg;
>   va_list ap;
>   va_start( ap, 0 );
    // while ((arg = va_arg(ap,int)) != 0)
    for (arg=first; arg; arg = va_arg(ap,int))
>     printf( "%d ", arg );
>   va_end( ap );
> }

Very little change from your version. However, now calling print like
this:
    print(); // Oops! Forgot the trailing 0!
is an error.

Work hard enough, you might convince me that there are uses for a
function with ellipsis being called without any arguments... but
so far, nobody's made a convincing case.

It's easy to contrive a function where we might want to do this:

    int foo_arg_count;
    void foo(...) {
        va_list va;
        va_start(ap, 0); // If this was legal
        for (int i=0; i<foo_arg_count; ++i)
            std::cout << va_arg(ap, int) << std::endl;
    }
As someone else proposed, we're using a global variable to indicate how
many arguments we plan to pass. But surely this is inferior to passing
the number of meaningful arguments as the first argument, which puts us
back into the previous case.

If someone has a NON-contrived case of a function with ellipsis not
wanting an initial argument, please post it.

> Anyway, it seems to me that implementing va_start( ap, 0 ) would require
> compiler support in cases where va_start( ap, arg ) does not (if parameters
> are always in stack, va_start needs just to take the address of arg).

Consider that phrase "compiler support." In what way would the compiler
support the va_arg macro? Would it have to push the number of arguments
onto the stack? If so, you've just changed the calling convention for
ALL functions that use the ellipsis... meaning that libraries for the
next version of the compiler have to be incompatible with libraries for
the old version!

If the compiler had to help in some other way, what would it be?

> So, it
> would be a nuisance without much benefit (IMHO).

Nuisance? It would be like heart surgery without anesthesia!

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 28 Aug 2002 17:50:11 GMT
Raw View
Hello,

If a function is declared precisely as

    <return_type> foo(...);

it is rather difficult to begin enumerating unnamed parameters
because the 'va_start' macro requires the parameter right before
the ellipsis.

It may not be truly useful, and in the light of existence of
overloading in C++, the ellipsis were probably adopted only for
compatibility with C, but I am curious (and the question has
probably come up before, so feel free to point me to an older
discussion if it's available), could it be possible to define
'va_start' so that passing, say, 0, or the function name itself,
would mean that there is no parameter before it, just start from
the beginning?  I have not written a compiler, so, unfortunately
I don't know how difficult that might be.

Thank you.

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: iddw@hotmail.com (Dave Hansen)
Date: Wed, 28 Aug 2002 13:28:46 CST
Raw View
On 28 Aug 2002 17:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
wrote:

>Hello,
>
>If a function is declared precisely as
>
>    <return_type> foo(...);
>
>it is rather difficult to begin enumerating unnamed parameters
>because the 'va_start' macro requires the parameter right before
>the ellipsis.
>
>It may not be truly useful, and in the light of existence of
>overloading in C++, the ellipsis were probably adopted only for
>compatibility with C, but I am curious (and the question has
>probably come up before, so feel free to point me to an older
>discussion if it's available), could it be possible to define
>'va_start' so that passing, say, 0, or the function name itself,
>would mean that there is no parameter before it, just start from
>the beginning?  I have not written a compiler, so, unfortunately
>I don't know how difficult that might be.
>
Consider the implementation of foo.  How do you get the first
parameter if you don't know what type it is, or if it even exists?

Regards,

                               -=Dave
--
Change is inevitable, progress is not.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Barry Margolin <barmar@genuity.net>
Date: 28 Aug 2002 20:50:08 GMT
Raw View
In article <3d6d13e0.105366172@News.CIS.DFN.DE>,
Dave Hansen <iddw@hotmail.com> wrote:
>On 28 Aug 2002 17:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
>wrote:
>
>>Hello,
>>
>>If a function is declared precisely as
>>
>>    <return_type> foo(...);
>>
>>it is rather difficult to begin enumerating unnamed parameters
>>because the 'va_start' macro requires the parameter right before
>>the ellipsis.
>>
>>It may not be truly useful, and in the light of existence of
>>overloading in C++, the ellipsis were probably adopted only for
>>compatibility with C, but I am curious (and the question has
>>probably come up before, so feel free to point me to an older
>>discussion if it's available), could it be possible to define
>>'va_start' so that passing, say, 0, or the function name itself,
>>would mean that there is no parameter before it, just start from
>>the beginning?  I have not written a compiler, so, unfortunately
>>I don't know how difficult that might be.
>>
>Consider the implementation of foo.  How do you get the first
>parameter if you don't know what type it is, or if it even exists?

It would be possible for this information to be in global variables.

However, this would probably be poor design.  It would be better for
re-entrancy to have that information as the initial parameters to the
function, in which case they should be in the prototype.

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Wed, 28 Aug 2002 15:48:36 CST
Raw View
"Dave Hansen" <iddw@hotmail.com> wrote...
> On 28 Aug 2002 17:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
> wrote:
>
> >Hello,
> >
> >If a function is declared precisely as
> >
> >    <return_type> foo(...);
> >
> >it is rather difficult to begin enumerating unnamed parameters
> >because the 'va_start' macro requires the parameter right before
> >the ellipsis.
> >
> >It may not be truly useful, and in the light of existence of
> >overloading in C++, the ellipsis were probably adopted only for
> >compatibility with C, but I am curious (and the question has
> >probably come up before, so feel free to point me to an older
> >discussion if it's available), could it be possible to define
> >'va_start' so that passing, say, 0, or the function name itself,
> >would mean that there is no parameter before it, just start from
> >the beginning?  I have not written a compiler, so, unfortunately
> >I don't know how difficult that might be.
> >
> Consider the implementation of foo.  How do you get the first
> parameter if you don't know what type it is, or if it even exists?


How do other functions do that?  There are predefined ones for
handling "lists of pointers", etc.  In such cases you don't need
to have a special "format string" to have knowledge of the types.
Yes, they will misbehave if one passes a wrong argument.  So, it
is the same way with fprintf.  Needs to be documented.

Let me illustrate:

  void dosomethingonthelistofintegers(...)
  {
    int nextinteger;
    va_list arglist;

    va_start(arglist, 0); // special case -- not in Standard

    do
    {
      nextinteger = va_arg(arglist, int);
      if (nextinteger)
      {
        // do something with nextinteger
      }
    }
    while (nextinteger);

    va_end(arglist);
  }

  int main()
  {
    dosomethingonthelistofintegers(1,2,3,4,5,6,0);
    dosomethingonthelistofintegers(9,8,7,6,5,4,3,2,1,0);
  }

The other possibility is to use the function name:

  va_start(arglist, dosomethingonthelistofintegers);
                         // special case -- not in Standard

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Tzvetan Mikov" <ceco@jupiter.com>
Date: 28 Aug 2002 20:50:18 GMT
Raw View
"Dave Hansen" <iddw@hotmail.com> wrote in message
news:3d6d13e0.105366172@News.CIS.DFN.DE...
> On 28 Aug 2002 17:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
> wrote:
>
> >Hello,
> >
> >If a function is declared precisely as
> >
> >    <return_type> foo(...);
> >
> >it is rather difficult to begin enumerating unnamed parameters
> >because the 'va_start' macro requires the parameter right before
> >the ellipsis.
>[...]
> Consider the implementation of foo.  How do you get the first
> parameter if you don't know what type it is, or if it even exists?

One can never know what their types are or even whether there are any
variable arguments at all, but it is assumed that some convention is being
followed (e.g. the format convention of printf/scanf).
The convention could be, for example, that the function takes a variable,
but greater than 0, number of arguments and the last one is 0.

void print (...)
{
  int arg;
  va_list ap;
  va_start( ap, 0 );
  while ((arg = va_arg(ap,int)) != 0)
    printf( "%d ", arg );
  va_end( ap );
}

Anyway, it seems to me that implementing va_start( ap, 0 ) would require
compiler support in cases where va_start( ap, arg ) does not (if parameters
are always in stack, va_start needs just to take the address of arg). So, it
would be a nuisance without much benefit (IMHO).

-tzvetan


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Hyman Rosen <hyrosen@mail.com>
Date: Wed, 28 Aug 2002 16:30:21 CST
Raw View
Victor Bazarov wrote:
 > could it be possible to define 'va_start' so that passing, say,
 > 0, or the function name itself, would mean that there is no
 > parameter before it, just start from the beginning?

First of all, the stdarg stuff comes directly from C, so that's
the place to address it. Second, since this is all implementation
magic anyway, there's no real need for ParmN at all, except that
on old architectures, va_start just took its address.

I seem to recall that Borland's C++ compiler always ignored ParmN,
and the macro expansion of va_start actually contained &..., as if
the ellipsis was a parameter name. GCC just exapnds eveything into
__builtin constructs.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: iddw@hotmail.com (Dave Hansen)
Date: 28 Aug 2002 22:20:01 GMT
Raw View
On 28 Aug 2002 20:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
wrote:

>"Dave Hansen" <iddw@hotmail.com> wrote...
>> On 28 Aug 2002 17:50:11 GMT, "Victor Bazarov" <vAbazarov@dAnai.com>
>> wrote:
>>
>> >Hello,
>> >
>> >If a function is declared precisely as
>> >
>> >    <return_type> foo(...);
>> >
>> >it is rather difficult to begin enumerating unnamed parameters
>> >because the 'va_start' macro requires the parameter right before
>> >the ellipsis.
>> >
[...]
>> Consider the implementation of foo.  How do you get the first
>> parameter if you don't know what type it is, or if it even exists?
>
>
>How do other functions do that?  There are predefined ones for
>handling "lists of pointers", etc.  In such cases you don't need
>to have a special "format string" to have knowledge of the types.

All I'm saying is the difference between

   <return type> foo(...);

and

   <return type> foo(<parm type> parm1, ...);

is that the first might be called with no parameters at all.  You need
a way to determine if this is the case in the implementation of foo.

>Yes, they will misbehave if one passes a wrong argument.  So, it
>is the same way with fprintf.  Needs to be documented.
>
>Let me illustrate:
>
>  void dosomethingonthelistofintegers(...)
>  {
>    int nextinteger;
>    va_list arglist;
>
>    va_start(arglist, 0); // special case -- not in Standard
>
>    do
>    {
>      nextinteger = va_arg(arglist, int);

My question is "what is nextinteger if the call was
"dosomethingonthelistofintegers();"?

>      if (nextinteger)
>      {
>        // do something with nextinteger
>      }
>    }
>    while (nextinteger);
>
>    va_end(arglist);
>  }

Consider an alternate implementation using the current standard:

  void dosomethingonthelistofintegers(int first, ...)
  {
    int nextinteger;
    va_list arglist;

    nextinteger = first;
    va_start(arglist, first);

    while (nextinteger)
    {
      /* Do something with nextinteger. */
      nextinteger = va_arg(arglist, int);
    }

    va_end(arglist);
  }

Regards,

                               -=Dave
--
Change is inevitable, progress is not.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Zack Weinberg <zackw@panix.com>
Date: Wed, 28 Aug 2002 18:05:25 CST
Raw View
In comp.std.c, Hyman Rosen  <hyrosen@mail.com> writes:
>
>I seem to recall that Borland's C++ compiler always ignored ParmN,
>and the macro expansion of va_start actually contained &..., as if
>the ellipsis was a parameter name. GCC just exapnds eveything into
>__builtin constructs.

And the only use GCC makes of the ParmN parameter to the __builtin
variety of va_start, is to issue a diagnostic if the programmer
specified anything other than the last named argument.

zw

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]