473,473 Members | 1,982 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

va_start problem

Why it is that following program behaving like this:

1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 void comd(char *p,int a, ...);
6 void f(void);
7
8 main(){
9 f();
10 }
11
12 void f(void) {
13 char *p = (char *)malloc(10);
14 comd(p,5,'p','a','d','h','j');
15
16 }
17 void comd(char *p,int a, ...)
18 {
19 int i;
20
21 char *q;
22
23 va_list ap;
24 va_start(ap,a);
25 q=p;
26 for(i=0;i<=a;i++)
27 {
28 *p++ = va_arg(ap,char);
29 }
30 printf("\n p = %s\n",q);
31 va_end(ap);
32 }
33
above program give output as
p = padhj
Now if i change line nos 14 to
comd(p,4,'p','a','d','h','j');
then also output is same?
how how va_start exactly locate startingg point
in ap?

Nov 15 '05 #1
17 2347
gyan wrote:

Why it is that following program behaving like this:

1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 void comd(char *p,int a, ...);
6 void f(void);
7
8 main(){
9 f();
10 }
11
12 void f(void) {
13 char *p = (char *)malloc(10);
14 comd(p,5,'p','a','d','h','j');
15
16 }
17 void comd(char *p,int a, ...)
18 {
19 int i;
20
21 char *q;
22
23 va_list ap;
24 va_start(ap,a);
25 q=p;
26 for(i=0;i<=a;i++)
In this case, you will go from 0 though 5, for a total of _6_ items.
That should be "i < a".
27 {
28 *p++ = va_arg(ap,char);
29 }
30 printf("\n p = %s\n",q);
31 va_end(ap);
32 }
33
above program give output as
p = padhj
Actually, the output included an extra character after the 'j', as
you ran off the end of your list. Apparently, whatever happened to
be there ended up being a non-printable character, and you didn't
see it.
Now if i change line nos 14 to
comd(p,4,'p','a','d','h','j');
then also output is same?
how how va_start exactly locate startingg point
in ap?


--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 15 '05 #2
gyan wrote:
Why it is that following program behaving like this:

1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 void comd(char *p,int a, ...);
6 void f(void);
7
8 main(){ int main(void) { // Read FAQ to know why 9 f(); return 0; // Read FAQ to know why 10 }
11
12 void f(void) {
13 char *p = (char *)malloc(10); // need to include stdlib.h // Read FAQ to know why
char *p = malloc(10); // Read FAQ to know why 14 comd(p,5,'p','a','d','h','j');
15
16 }
17 void comd(char *p,int a, ...)
18 {
19 int i;
20
21 char *q;
22
23 va_list ap;
24 va_start(ap,a);
25 q=p;
26 for(i=0;i<=a;i++) for(i=0;i<a;i++) // to add a number of elements..
// you were adding a+1 27 {
28 *p++ = va_arg(ap,char);
29 } *p = '\0'; // null terminate the string 30 printf("\n p = %s\n",q);
31 va_end(ap);
32 }
33
above program give output as
p = padhj
Now if i change line nos 14 to
comd(p,4,'p','a','d','h','j');
then also output is same?
how how va_start exactly locate startingg point
in ap?

Nov 15 '05 #3
gyan wrote:
Why it is that following program behaving like this: [....] how how va_start exactly locate startingg point
in ap?
That is not your problem.

No one knows why your program does as it does; you have no reason to
expect it to run at all.

This line might well cause your program to abort: 28 *p++ = va_arg(ap,char); All the arguments are ints.

This line leads to trying to get more arguments than there are 26 for(i=0;i<=a;i++)
and your failure to terminate the string properly means that 30 printf("\n p = %s\n",q); leads to pssibly disastrous outcomes.

Compare your code to the following, paying attention to the lines marked
with /* mha */:

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

void comd(char *p, int a, ...);
#define BIGENOUGH 1024

int /* mha */ main()
{
char p[BIGENOUGH];
comd(p, 5, 'p', 'a', 'd', 'h', 'j');
comd(p, 4, 'p', 'a', 'd', 'h', 'j');
return 0;
}
void comd(char *p, int a, ...)
{
int i;
char *q;
va_list ap;

printf("\n comd called with a = %d\n", a);
va_start(ap, a);
q = p;
for (i = 0; i < /* mha */ a; i++)
*p++ = va_arg(ap, int); /* mha */
*p = 0; /* mha */
printf("p = %s\n", q);
va_end(ap);
}
comd called with a = 5
p = padhj

comd called with a = 4
p = padh

[OP's code follows, with those obnoxious line numbers] 1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 void comd(char *p,int a, ...);
6 void f(void);
7
8 main(){
9 f();
10 }
11
12 void f(void) {
13 char *p = (char *)malloc(10);
14 comd(p,5,'p','a','d','h','j');
15
16 }
17 void comd(char *p,int a, ...)
18 {
19 int i;
20
21 char *q;
22
23 va_list ap;
24 va_start(ap,a);
25 q=p;
26 for(i=0;i<=a;i++)
27 {
29 }
30 printf("\n p = %s\n",q);
31 va_end(ap);
32 }
33

Nov 15 '05 #4
Anand wrote:
gyan wrote:
1 #include <stdlib.h>
[...] // need to include stdlib.h // Read FAQ to know why


An interesting observation. Since he did include <stdlib.h>, what's
your point?
Nov 15 '05 #5
gyan <si*****@anz.com> wrote:

28 *p++ = va_arg(ap,char);


In addition to the problems others have noted, arguments to varargs
functions undergo the default argument promotions which means that char
and short get promoted to int and float gets promoted to double, which
means that line should be:

*p++ = va_arg(ap, int);

-Larry Jones

Everybody's a slave to routine. -- Calvin
Nov 15 '05 #6
In article
<d1******************************@localhost.talkab outprogramming.com>,
"gyan" <si*****@anz.com> wrote:
Why it is that following program behaving like this:

1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4
5 void comd(char *p,int a, ...);
6 void f(void);
7
8 main(){
9 f();
10 }
11
12 void f(void) {
13 char *p = (char *)malloc(10);
14 comd(p,5,'p','a','d','h','j');
15
16 }
17 void comd(char *p,int a, ...)
18 {
19 int i;
20
21 char *q;
22
23 va_list ap;
24 va_start(ap,a);
25 q=p;
26 for(i=0;i<=a;i++) *****************

I think you meant
for (i = 0; i < a; i++)
27 {
28 *p++ = va_arg(ap,char);
29 }
At this point, you forgot to store a missing 0 character at the end of
the string.
30 printf("\n p = %s\n",q);
31 va_end(ap);
32 }
33
above program give output as
p = padhj
Now if i change line nos 14 to
comd(p,4,'p','a','d','h','j');
then also output is same?
how how va_start exactly locate startingg point
in ap?

Nov 15 '05 #7
la************@ugs.com wrote:
gyan <si*****@anz.com> wrote:
28 *p++ = va_arg(ap,char);

In addition to the problems others have noted, arguments to varargs\

s/In addition to/Among the problems/
See my post an hour and a half before yours.
functions undergo the default argument promotions which means that char
and short get promoted to int and float gets promoted to double, which
means that line should be:

*p++ = va_arg(ap, int);

Nov 15 '05 #8
in comp.lang.c i read:
See my post an hour and a half before yours.


ahh, someone repealed propagation effects from the usenet? about time!

--
a signature
Nov 15 '05 #9

la************@ugs.com wrote:
gyan <si*****@anz.com> wrote:

28 *p++ = va_arg(ap,char);


In addition to the problems others have noted, arguments to varargs
functions undergo the default argument promotions which means that char
and short get promoted to int and float gets promoted to double, which
means that line should be:

*p++ = va_arg(ap, int);


For a free-standing implementation, it may pay to be safer with...

#if UCHAR_MAX > INT_MAX
*p++ = va_arg(ap, unsigned);
#else
*p++ = va_arg(ap, int);
#endif

--
Peter

Nov 15 '05 #10
Martin Ambuhl wrote:
Anand wrote:
gyan wrote:
1 #include <stdlib.h>


[...]
// need to include stdlib.h // Read FAQ to know why

An interesting observation. Since he did include <stdlib.h>, what's
your point?

Oops.. I missed it (sorry gyan), probably (1%) due to small indentation
and mostly (99%) due to my negligence..
Nov 15 '05 #11
Martin Ambuhl wrote:
Anand wrote:
gyan wrote:
1 #include <stdlib.h>


[...]
// need to include stdlib.h // Read FAQ to know why

An interesting observation. Since he did include <stdlib.h>, what's
your point?

Oops.. I missed it.

I missed it due to small indentation change (1%) and
mostly due to my negligenc (99% .)

sorry gyan.
Nov 15 '05 #12
Martin Ambuhl wrote:
gyan wrote: [...]
This line might well cause your program to abort:
> 28 *p++ = va_arg(ap,char);

All the arguments are ints.

[...]
if the chars are always promoted to int in variadic function then why
there's va_arg(ap,char)?
I mean.. why would it be different from va_arg(ap,int)?
Did I miss something?
Nov 15 '05 #13
Anand wrote:
Martin Ambuhl wrote:
gyan wrote:
[...]
This line might well cause your program to abort:
> 28 *p++ = va_arg(ap,char);

All the arguments are ints.


[...]
if the chars are always promoted to int in variadic function then why
there's va_arg(ap,char)?


Who said that there _is_, in any meaningful sense, 'va_arg(ap,char)'?
va_arg is a macro, so you can make all sorts of nonsensical strings
involving it.
Any function not governed by a prototype (or as an argument in the '...'
part of a prototype) will have its argument expressions converted by the
usual argument conversions. Any argument with rank less than int will
be converted to int if the type is signed or if all the values of that
type can be represented as an int, otherwise to unsigned int. Types of
rank less than int include short, unsigned short, char, unsigned char,
signed char, and _Bool.

Note that C99 retains the float->double conversion here even though it
doesn't in the usual unitary conversions.
I mean.. why would it be different from va_arg(ap,int)?
unless sizeof(int) == sizeof(char), there is an obvious difference. The
other one is that 'va_arg(ap, char)' has no coherent meaning, since the
argument is never a char.
Did I miss something?


Or else added something.
Nov 15 '05 #14
Martin Ambuhl wrote:
Anand wrote:
Martin Ambuhl wrote:
gyan wrote:

[...]
This line might well cause your program to abort:
> 28 *p++ = va_arg(ap,char);
All the arguments are ints.

[...]
if the chars are always promoted to int in variadic function then why
there's va_arg(ap,char)?

Who said that there _is_, in any meaningful sense, 'va_arg(ap,char)'?

[...]
Bad wordings from my side :-(

I wanted to know the behavior/usage of va_arg(ap, char), if at all?
I got the answer now " *NO* meaningful usage."
Thanks for clarifying
I knew that integer promotions in variadic functions.. But somehow I
thought va_arg would handle this.
To add to my confusion my compiler handled the smaller-than-int properly
sunch that if I write va_arg(ap, char) it would work (by making
something like to va_arg(ap, int)).
Nov 15 '05 #15
la************@ugs.com wrote:
gyan <si*****@anz.com> wrote:

14 comd(p,5,'p','a','d','h','j');

17 void comd(char *p,int a, ...)
23 va_list ap;
24 va_start(ap,a);
28 *p++ = va_arg(ap,char);


In addition to the problems others have noted, arguments to varargs
functions undergo the default argument promotions which means that
char and short get promoted to int and float gets promoted to double,
which means that line should be:

*p++ = va_arg(ap, int);


True, but the arguments were all ints in the first place, so no
promotion occurs in this particular example.

Nov 15 '05 #16
Hi all,
thanks for your replies.
I got, what was wrong with my program.
But, no body pointed out how va_start locate starting point of variable
argument list?
in my program, does it depends on value of a or *p.
Or it is like that va_arg will always fetch 'p' first time and then carry
on to 2nd argument and so on?

Nov 15 '05 #17
in comp.lang.c i read:
But, no body pointed out how va_start locate starting point of variable
argument list?


you tell it.

--
a signature
Nov 15 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: frankg | last post by:
When I compile this file ------------------------------------------------------ #include <stdarg.h> template <class Any> void var_arg_func(int dimension_count, ...) { int dimensions;...
6
by: John Harrison | last post by:
Is the following code OK? #include <stdarg.h> void func(const X& x) { va_list args; va_start(args, x); funcv(x, args); va_end(args);
3
by: Douwe | last post by:
I try to build my own version of printf which just passes all arguments to the original printf. As long as I keep it with the single argument version everything is fine. But their is also a version...
1
by: Minti | last post by:
I was just checking http://docs.freebsd.org/info/gcc/gcc.info.Varargs.html and http://www-ccs.ucsd.edu/c/stdarg.html I seemed to have never given this simple thing much thought, but I...
4
by: Sekhar | last post by:
While using variable arguments we have to initialize variable argument like va_start( arg_ptr, prevParam ); Can any body explain what is the significance of second parameter(prevParam) while...
5
by: Ross | last post by:
Hi, I have the following program: #include <stdarg.h> class A { public: A() { } }
3
by: mahesha | last post by:
What should be the behaviour of following program?. Is this behaviour is undefined or compiler should report error for this case?. Can anybody point me to pages in the standard where it is...
8
by: Manju | last post by:
Hi All, I am facing a strange issue. if the string passed to va_start()/vsnprintf() contains "%n", there is a segmentation fault. If it's replaced with any other character, no issues. Any idea...
4
by: mainargv | last post by:
hi How do you rewrite codes with " ... va_list va_start va_etc", so that simple c compiler don't have to deal with them. I have written a simple c->verilog compiler but it can't deal with...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.