Modifying an arg of va_list

J

Jon

Is it possible to modify an argument of a va_list and then pass the
modified va_list to other functions?

void c_fun1(int, va_list args)
{
int *firstIntPointer = &(va_arg(args, int));

*firstIntPointer = 2; // a new value
}

void c_fun(int v, va_list args)
{
c_fun1(v, args);
c_fun2(v, args); // c_fun2 expects the modified int
}

It seems that Windows/Hp/SOlaris/AIX all work, but Linux is giving g++
compiler errors.

error: non-lvalue in unary `&'

Thank you.
Jon
 
M

Michael Mair

Jon said:
Is it possible to modify an argument of a va_list and then pass the
modified va_list to other functions?

Not in standard C.
There is nothing known about the type va_list apart from the typical
usage via va_start/va_arg/va_end; va_arg may well evaluate to an
rvalue extracted by obscure means from somewhere, instead of being the
equivalent of some *(cast to ptr to demanded type)currentpos.
void c_fun1(int, va_list args)
{
int *firstIntPointer = &(va_arg(args, int));

*firstIntPointer = 2; // a new value
}

void c_fun(int v, va_list args)
{
c_fun1(v, args);
c_fun2(v, args); // c_fun2 expects the modified int
}

It seems that Windows/Hp/SOlaris/AIX all work, but Linux is giving g++
compiler errors.

error: non-lvalue in unary `&'

Which proves the point that one should not rely on undefined behaviour.

BTW: g++ is a C++ compiler.
If you are compiling some program in the common semantically
incompatible subset, you should consider switching to either
real C or real C++. For the latter, the people at comp.lang.c++
can help you better (and may tell you that variable argument
lists are more a sign of poor design than useful).
For the former: consider another interface or splitting
the things accordingly (you can pass the "remainder" of an
original va_list after several va_arg "calls" preceded by the
non-variable information you want to pass. Or you can give the
full va_list plus the position to be overridden by a separately
given argument.).

Cheers
Michael
 
C

CBFalconer

Michael said:
.... snip ...

BTW: g++ is a C++ compiler.
If you are compiling some program in the common semantically
incompatible subset, you should consider switching to either
real C or real C++. For the latter, the people at comp.lang.c++
can help you better (and may tell you that variable argument
lists are more a sign of poor design than useful).

Hell, I'll tell you that right here. Variadic functions harbor
large and small biting insects. Unfortunately their use is
ingrained in the C community. They can be replaced by a much more
effective set of properly characterized routines.
 
A

Alan Balmer

Hell, I'll tell you that right here. Variadic functions harbor
large and small biting insects. Unfortunately their use is
ingrained in the C community. They can be replaced by a much more
effective set of properly characterized routines.

Oh, I dunno. I kind of like printf() ;-)
 
S

SM Ryan

# Is it possible to modify an argument of a va_list and then pass the
# modified va_list to other functions?
#
# void c_fun1(int, va_list args)
# {
# int *firstIntPointer = &(va_arg(args, int));

Unless va_arg is a #define which yields an lvalue, or the compiler turns
it into something that return an lvalue, you cannot take the address of
it. What you're doing is as sensible as (&(1+2)).
 
M

Michael Mair

CBFalconer said:
Michael Mair wrote:

... snip ...


Hell, I'll tell you that right here. Variadic functions harbor
large and small biting insects. Unfortunately their use is
ingrained in the C community. They can be replaced by a much more
effective set of properly characterized routines.

*g* Mostly, yes. I did and do not want to open this discussion here...

<OT>
I just want to add that the C++ people have operator and function
overloading for the few cases where the convenience or clarity
definitely speak in favour (or everything else not too much against)
variable arguments, so there essentially cannot be a founded defense
of the good old ellipsis notation, IMO.
</OT>

Cheers
MIchael
 
J

Jon

Michael,

Thank you very much for the info.

Jon

Michael said:
Not in standard C.
There is nothing known about the type va_list apart from the typical
usage via va_start/va_arg/va_end; va_arg may well evaluate to an
rvalue extracted by obscure means from somewhere, instead of being the
equivalent of some *(cast to ptr to demanded type)currentpos.


Which proves the point that one should not rely on undefined behaviour.

BTW: g++ is a C++ compiler.
If you are compiling some program in the common semantically
incompatible subset, you should consider switching to either
real C or real C++. For the latter, the people at comp.lang.c++
can help you better (and may tell you that variable argument
lists are more a sign of poor design than useful).
For the former: consider another interface or splitting
the things accordingly (you can pass the "remainder" of an
original va_list after several va_arg "calls" preceded by the
non-variable information you want to pass. Or you can give the
full va_list plus the position to be overridden by a separately
given argument.).

Cheers
Michael
 
J

Jon

SM,

Thanks a lot for the info. Just the answer I am afraid of. I will
have to redo some work.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top