va_list处理有问题 [英] Trouble with va_list processing

查看:92
本文介绍了va_list处理有问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我写了一个非常简单的程序,使用可变参数调用和



得到奇怪的东西我无法解释。


我有一个显示两个参数的函数(add)。当我直接调用它时,它运行良好



现在我有第二个函数(set)也调用add。但这个

并不是
工作。


这是我的程序生成的输出。我不明白为什么我会得到不同的结果(我试过Borland C ++ Builder和Visual

C ++,和

我得到类似的结果)。


任何帮助将不胜感激。

谢谢

最好的问候

Thierry

Hi,

I have written a very simple program using variable arguments calls and
I
get strange things that I cannot explain.

I have one function (add) that displays two parameters. It works well
when I call it directly.
Now I have a second function (set) that also calls add. But this
doesn''t
work.

Here is the output generated by my program. I don''t understand why I
get different result (I tried on both Borland C++ Builder and in Visual
C++, and
I got similar results).

Any help would be greatly appreciated.
Thanks
Best Regards
Thierry

ADD
format = H%dW%d

arg [] = 1234

arg [] = 5678

SET
ADD format = H%dW%d
arg[] = 1234
arg[] = 5678
SET



格式= H%dW%d

arg [] = 1245060

arg [] = 1245060


#include< stdio.h>

#include< stdarg.h>


// ------------ -------------------------------------------------- -------------

void add(char * format,...)

{

va_list arg_ptr;

va_start(arg_ptr,format);


printf(" format =%s \ n",format);

printf(& ; arg [] =%d \ n",va_arg(arg_ptr,unsigned long));

printf(" arg [] =%d \ n",va_arg(arg_ptr,unsigned)长));

}

// --------------------------- ------------------------------------------------ <无线电通信/>
void set(char * format,...)

{

va_list arg_ptr;

va_start(arg_ptr,format );

add(format,arg_ptr);

}

// -------------- -------------------------------------------------- -----------

int main()

{

printf(" \\\
>> > ADD \ n");

add(" H%dW%d&q​​uot;,1234,5678);


printf(" \\ \\ n>>> SET \ n");

set(" H%dW%d&q​​uot;,1234,5678);


返回0;

}


format = H%dW%d
arg[] = 1245060
arg[] = 1245060


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

//---------------------------------------------------------------------------
void add (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);

printf("format = %s\n",format);
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
}
//---------------------------------------------------------------------------
void set (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);
add(format, arg_ptr);
}
//---------------------------------------------------------------------------
int main()
{
printf("\n>>>ADD \n");
add("H%dW%d",1234,5678);

printf("\n>>>SET \n");
set("H%dW%d",1234,5678);

return 0;
}

推荐答案

" thierrydollar" <第***** @ tetraedre.com>写道:
"thierrydollar" <th*****@tetraedre.com> writes:
我写了一个非常简单的程序,使用变量参数调用
我得到了一些我无法解释的奇怪的东西。

我有一个函数(add)显示两个参数。当我直接调用它时它很好用。现在我有第二个函数(set)
也调用add。但这不起作用。

这是我的程序生成的输出。我不明白为什么我得到不同的结果(我尝试了Borland C ++ Builder和Visual C ++,我得到了类似的结果)。
I have written a very simple program using variable arguments calls
and I get strange things that I cannot explain.

I have one function (add) that displays two parameters. It works
well when I call it directly. Now I have a second function (set)
that also calls add. But this doesn''t work.

Here is the output generated by my program. I don''t understand why I
get different result (I tried on both Borland C++ Builder and in
Visual C++, and I got similar results).



我假设您同时使用它们作为C编译器;如果你使用它们作为C ++编译器,那么你就错了。你的程序似乎是在b和C ++的公共子集中,但有微妙的

差异。


[snip] ]



I assume you were using both as C compilers; if you''re using them as
C++ compilers, you''re in the wrong newsgroup. Your program appears to
be within the common subset of C and C++, but there are subtle
differences.

[snip]

ADD格式= H%dW%d
arg [] = 1234
arg [] = 5678
SET
ADD format = H%dW%d
arg[] = 1234
arg[] = 5678
SET


格式= H%dW%d
arg [] = 1245060
arg [] = 1245060

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

// ----------- -------------------------------------------------- --------------
void add(char * format,...)
{
va_list arg_ptr;
va_start(arg_ptr,format );

printf(" format =%s \ n",format);
printf(" arg [] =%d \ n",va_arg(arg_ptr,unsigned) long));
printf(" arg [] =%d \ n",va_arg(arg_ptr,unsigned long));
}
// ------- -------------------------------------------------- --------------- ---
void set(char * format,...)
{
va_list arg_ptr;
va_start(arg_ptr,format);
add(format,arg_ptr );
}
// ------------------------------------- --------------------------------------
int main()
{
printf(" \\\
>>> ADD \ n");
add(" H%dW%d&q​​uot;,1234,5678);

printf(" \\\
>>> SET \ n");
设置(H%dW%d,1234,5678);

返回0;
}


format = H%dW%d
arg[] = 1245060
arg[] = 1245060


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

//---------------------------------------------------------------------------
void add (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);

printf("format = %s\n",format);
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
}
//---------------------------------------------------------------------------
void set (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);
add(format, arg_ptr);
}
//---------------------------------------------------------------------------
int main()
{
printf("\n>>>ADD \n");
add("H%dW%d",1234,5678);

printf("\n>>>SET \n");
set("H%dW%d",1234,5678);

return 0;
}




您对add()的调用不正确,但无论如何都可能正常工作。

当它处理时电话

add(H%dW%d,1234,5678);

编译器不知道add()期望unsigned long

参数。常量1234和5678的类型为int。尝试

add("%dW%d&q​​uot;,1234UL,5678UL);



add("%dW%d&q​​uot; ;,(unsigned long1234,(unsigned long)5678);

或更改va_arg()调用以使用int。


这很可能是工作如果int和long是相同的大小,或者如果

他们通过兼容的调用约定和字节

订购恰到好处。


(另外,由于标准* printf()函数对int类型使用%d,

似乎误导add()将其用于unsigned long 。大概是

add()的完整版本注意格式字符串 - 但是

感谢您删除了那部分代码。)


你忘了在add()中调用va_end()。

add()函数需要一个char *参数后跟零或更多

未知类型的参数;因为它调用类型为

unsigned long的va_arg(),它将是我nvoke未定义的行为,除非你用char *和两个unsigned long来调用

。在set()中,使用

char *和va_list调用add()。 add()函数可能会尝试将va_list值解释为

,就像它是一个无符号长整数,然后尝试解释任何垃圾碰巧是第三个参数的地方

*会被存储,就好像它是一个无符号长 - 并且只有一些乐观的假设才能存储。它是未定义的行为。


通过类比标准的'printf()与vprintf(),你可以创建

a的第二个函数,比如vadd(),它需要一个格式字符串和一个

va_list。你的add()函数可以实现为:


void add(char * format,...)

{

va_list arg_ptr;

va_start(arg_ptr,format);

vadd(格式,arg_ptr);

va_end(arg_ptr);

}


(我只对该代码的变体进行了最低限度的测试;请谨慎使用。)


- -

Keith Thompson(The_Other_Keith) ks***@mib.org < http:// www .ghoti.net / ~kst>

圣地亚哥超级计算机中心< *> < http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。



Your call to add() is incorrect, but is likely to work anyway.
When it processes the call
add("H%dW%d",1234,5678);
the compiler doesn''t know that add() is expecting unsigned long
arguments. The constants 1234 and 5678 are of type int. Try either
add("%dW%d", 1234UL, 5678UL);
or
add("%dW%d", (unsigned long1234, (unsigned long)5678);
or change the va_arg() invocations to use int.

This is likely to "work" if int and long are the same size, or if
they''re passed with compatible calling conventions and the byte
ordering is just right.

(Also, since the standard *printf() functions use "%d" for type int,
it seems misleading for add() to use it for unsigned long. Presumably
the full version of add() pays attention to the format string -- but
thank you for stripping out that part of the code.)

You forgot to call va_end() in add().

The add() function requires a char* argument followed by zero or more
arguments of unknown types; since it invokes va_arg() with a type of
unsigned long, it will invoke undefined behavior unless you call it
with a char* and two unsigned longs. In set(), you call add() with a
char* and a va_list. The add() function probably tries to interpret
the va_list value as if it were an unsigned long, and then tries to
interpret whatever garbage happens to be where the third argument
*would* have been stored as if it were an unsigned long -- and that''s
only with some optimistic assumptions. It''s undefined behavior.

By analogy with the standard''s printf() vs. vprintf(), you can create
a second function, say vadd(), that takes a format string and a
va_list. Your add() function could then be implemented as:

void add(char *format, ...)
{
va_list arg_ptr;
va_start(arg_ptr, format);
vadd(format, arg_ptr);
va_end(arg_ptr);
}

(I''ve only minimally tested a variant of this code; use with caution.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


thierrydollar写道:
thierrydollar wrote:
我编写了一个非常简单的程序,使用变量参数调用和<我得到了一些我无法解释的奇怪的事情。
#include< stdio.h>
#include< stdarg.h>

// ---------------- -------------------------------------------------- ---------
void add(char * format,...)
{
va_list arg_ptr;
va_start(arg_ptr,format);

printf(" format =%s \ n",format);
printf(" arg [] =%d \ n",va_arg(arg_ptr,unsigned long));
printf(" arg [] =%d \ n",va_arg(arg_ptr,unsigned long));
}
// ------------ -------------------------------------------------- -------------
void set(char * format,...)
{
va_list arg_ptr;
va_start(arg_ptr,format) ;
add(format,arg_ptr);


函数add期望第二个和第三个参数的类型为

unsigned long,但你传递的是第一个类型的arg_ptr而没有任何东西。结果是未定义的行为。

}
// ----------------------------- ----------------------------------------------
int main()
{/> printf(" \ n>>> ADD \ n");
add(" H%dW%d&q​​uot;,1234,5678) );


Add需要两个unsigned long类型的参数。您提供了两个类型为int的
参数。它可能适用于你的系统,如果int和long是相同大小的b $ b,但实践很差而且不便携。

printf(" \\\
>>> ; SET \ n");
设置(H%dW%d,1234,5678);

返回0;
}
I have written a very simple program using variable arguments calls and
I get strange things that I cannot explain. #include <stdio.h>
#include <stdarg.h>

//---------------------------------------------------------------------------
void add (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);

printf("format = %s\n",format);
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
printf("arg[] = %d\n", va_arg (arg_ptr, unsigned long));
}
//---------------------------------------------------------------------------
void set (char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);
add(format, arg_ptr);
The function add expects the second and third argument to be of type
unsigned long, but you pass it a type arg_ptr for the first and nothing
for the second. The result is undefined behavior.
}
//---------------------------------------------------------------------------
int main()
{
printf("\n>>>ADD \n");
add("H%dW%d",1234,5678);
Add expects two arguments of type unsigned long. You are providing two
arguments of type int. It may work on your system if int and long are
the same size, but is poor practice and not portable.
printf("\n>>>SET \n");
set("H%dW%d",1234,5678);

return 0;
}



-

Thad


--
Thad


我描述的问题与参数类型无关。在传递字符串时我也遇到了问题。

The problem I described is not related to the type of arguments. I had
also problems when passing strings.


这篇关于va_list处理有问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆