variable length arguments

S

srinivas reddy

Hi,
I have following questions.
1. Does va_arg allow one to read user defined types. My compiler
allows but I am wondering whether it is true for all.
2. I wrote the following code.
Pardon my omitting declarations etc..

int main()
{
func(10, "baaaaa");
}

void func(int i, ...)
{
va_list ap;
va_start(ap, i);
string* s = va_arg(ap, string*);
va_end(ap);

cout << (int) *s;
}

It prints 0x62616161. Why is this happening. I mean why is it casting
char to int and putting it in int*. And also I couldn't find where the
last two characters are stored. Could some body explain how va_arg
actually works. I know that variable length functions can be
substituted with virtual functions and overloaded functins but I am
curious.

tia,
Srinivas
 
R

Rob Williscroft

srinivas reddy wrote in
Hi,
I have following questions.
1. Does va_arg allow one to read user defined types. My compiler
allows but I am wondering whether it is true for all.

The types have to be POD (Plain Old Data) types, a POD is basicaly
a builtin type (int etc) or struct/union that could be compiled by
a C compiler (this is an over-simplification).
2. I wrote the following code.
Pardon my omitting declarations etc..

int main()
{
func(10, "baaaaa");
}

void func(int i, ...)
{
va_list ap;
va_start(ap, i);
string* s = va_arg(ap, string*);

What's string is it std::string or is it char or char *

This is what you need here:

char const *s = va_arg(ap, char const *);
va_end(ap);

cout << (int) *s;
}

It prints 0x62616161. Why is this happening.

Unless you tell us what "string" is we have know way of knowing.

Try:

std::cout << s << std::endl;
I mean why is it casting
char to int and putting it in int*.

I see now such thing ?
And also I couldn't find where the
last two characters are stored. Could some body explain how va_arg
actually works.

All thats important is that it does what the C++ Standard says it does.
Understand what the Standard say's you can do and do that.

How the va_arg macro works is defined by your implementation and
will vary considerably from one implementation to another.

I know that variable length functions can be
substituted with virtual functions and overloaded functins but I am
curious.

HTH

Rob.
 
J

John Harrison

srinivas reddy said:
Hi,
I have following questions.
1. Does va_arg allow one to read user defined types. My compiler
allows but I am wondering whether it is true for all.

It does not allow you to read user defined types. Pointers to user defined
types would be OK, but not UDT's themselves.
2. I wrote the following code.
Pardon my omitting declarations etc..

int main()
{
func(10, "baaaaa");
}

void func(int i, ...)
{
va_list ap;
va_start(ap, i);
string* s = va_arg(ap, string*);
va_end(ap);

cout << (int) *s;
}

It prints 0x62616161. Why is this happening. I mean why is it casting
char to int and putting it in int*.

You pass a char*, to read it as if it were a string*, then you dereference
and cast the string to an int. The code is rubbish, no-one can explain why
it is happening, its just wrong. Also nowhere in your code does 'it casting
char to int and putting it in int*'. I think you need to explain yourself
more carefully, and I also have a sneaking suspicion that the code you
posted is not the real code.
And also I couldn't find where the
last two characters are stored. Could some body explain how va_arg
actually works.

It doesn't work unless the types are correct. The types in the function call
are 'promoted', for instance char and short are converted to int, float is
converted to double, arrays are converted to pointers, pointers are
unchanged. Then when you get the parameter using va_arg, the type you use in
va_arg must match the promoted type used in the function call. If the types
aren't the same (like in your example above) then your code is wrong and
anything could happen.
I know that variable length functions can be
substituted with virtual functions and overloaded functins but I am
curious.

tia,
Srinivas

john
 
S

srinivas reddy

Thanks for your response. I was misled by man pages on my machine. I
was just exploring variable length args and testing what is possible
and what is not. I thought to receive a data type, I need to feed
pointer to that data type as second arg to va_arg. Thats why I used
string*. Then I tried all kinds to print what is returned using gdb
and only (int) *s printed something comprehensible for me although
code looked rubbish to me also. Apologise for posting without properly
understanding functionality.

Srinivas
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top