#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 calladd("H%dW%d",1234,5678);the compiler doesn''t know that add() is expecting unsigned longarguments. The constants 1234 and 5678 are of type int. Try eitheradd("%dW%d", 1234UL, 5678UL);oradd("%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 ifthey''re passed with compatible calling conventions and the byteordering 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. Presumablythe full version of add() pays attention to the format string -- butthank 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 morearguments of unknown types; since it invokes va_arg() with a type ofunsigned long, it will invoke undefined behavior unless you call itwith a char* and two unsigned longs. In set(), you call add() with achar* and a va_list. The add() function probably tries to interpretthe va_list value as if it were an unsigned long, and then tries tointerpret whatever garbage happens to be where the third argument*would* have been stored as if it were an unsigned long -- and that''sonly with some optimistic assumptions. It''s undefined behavior.By analogy with the standard''s printf() vs. vprintf(), you can createa second function, say vadd(), that takes a format string and ava_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. - Thad--Thad 这篇关于va_list处理有问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 23:55