📄 handoff.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN"><!-- This collection of hypertext pages is Copyright 1995-2005 by Steve Summit. --><!-- Content from the book "C Programming FAQs: Frequently Asked Questions" --><!-- (Addison-Wesley, 1995, ISBN 0-201-84519-9) is made available here by --><!-- permission of the author and the publisher as a service to the community. --><!-- It is intended to complement the use of the published text --><!-- and is protected by international copyright laws. --><!-- The on-line content may be accessed freely for personal use --><!-- but may not be published or retransmitted without explicit permission. --><!-- --><!-- this page built Sat Dec 24 21:47:46 2005 by faqproc version 2.7 --><!-- from source file varargs.sgml dated Sun Nov 25 08:09:42 2001 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/varargs/handoff.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:59:00 GMT --><head><meta name=GENERATOR content="faqproc"><title>Question 15.12</title><link href="funcptr.html" rev=precedes><link href="invvarargs.html" rel=precedes><link href="index.html" rev=subdocument></head><body bgcolor="#ffffff"><a href="funcptr.html" rev=precedes><img src="../images/buttonleft.gif" alt="prev"></a><a href="index.html" rev=subdocument><img src="../images/buttonup.gif" alt="up"></a><a href="invvarargs.html" rel=precedes><img src="../images/buttonright.gif" alt="next"></a> <a href="../index-2.html"><img src="../images/buttontop.gif" alt="top/contents"></a><a href="../search.html"><img src="../images/buttonsrch.gif" alt="search"></a><hr><p><!-- qbegin --><h1>comp.lang.c FAQ list<font color=blue>·</font><!-- qtag -->Question 15.12</h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I write a function which takes a variable number ofarguments and passes them to some other function (which takes a variable number of arguments)?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In general, you cannot.Ideally,you should provide a version of that other function which accepts a<TT>va_list</TT> pointer.</p><p>Suppose you want to write a <TT>faterror</TT> functionwhich will print a fatal error message, then exit.You might like to write it in terms of the <TT>error</TT> function of question <a href="vprintf.html">15.5</a>:<pre> void faterror(const char *fmt, ...) { error(fmt, <I>what goes here?</I> ); exit(EXIT_FAILURE); }</pre>but it's not obvious how to hand <TT>faterror</TT>'s arguments off to <TT>error</TT>.</p><p>Proceed as follows.First split up the existing <TT>error</TT> functionto create a new <TT>verror</TT>which accepts not a variable argument listbut a single <TT>va_list</TT> pointer.(Note that doing so is littleextra work,because <TT>verror</TT> contains much of the codethat used to be in <TT>error</TT>,and the new <TT>error</TT> becomes a simple wrapperaround <TT>verror</TT>.)<pre>#include <stdio.h>#include <stdarg.h>void verror(const char *fmt, va_list argp){ fprintf(stderr, "error: "); vfprintf(stderr, fmt, argp); fprintf(stderr, "\n");}void error(const char *fmt, ...){ va_list argp; va_start(argp, fmt); verror(fmt, argp); va_end(argp);}</pre></p><p>Now you can write <TT>faterror</TT>,and have it call <TT>verror</TT>, too:<pre>#include <stdlib.h>void faterror(const char *fmt, ...){ va_list argp; va_start(argp, fmt); verror(fmt, argp); va_end(argp); exit(EXIT_FAILURE);}</pre>Note that therelationbetween <TT>error</TT> and <TT>verror</TT>is exactly that which holds betweene.g. <TT>printf</TT> and <TT>vprintf</TT>.In fact,as Chris Torek has observed,whenever you find yourself writing a varargs function,it's a good idea to write two versions of it:one(like <TT>verror</TT>)whichaccepts a <TT>va_list</TT> and does the work,and one(like the revised <TT>error</TT>)which is a simple wrapper.The only real restriction on this techniqueis thata function like <TT>verror</TT>can scan the arguments just once;there is no way for it to reinvoke va_start.</p><p>If you do not have the optionof rewritingthe lower-level function(<TT>error</TT>, in this example)to accept a <TT>va_list</TT>,such that you find yourself needing to passthe variable arguments thatone function(e.g. <TT>faterror</TT>)receiveson to another as actual arguments,no portable solution is possible.(The problemcould perhapsbe solved by resorting to machine-specificassembly language;see alsoquestion <a href="invvarargs.html">15.13</a>.)</p><p>One approach that would <em>not</em> work would be something like<pre> void faterror(const char *fmt, ...) { va_list argp; va_start(argp, fmt); error(fmt, argp); /* WRONG */ va_end(argp); exit(EXIT_FAILURE); }</pre>A<TT>va_list</TT> is<em>not</em>itself a variable argument list;it's really sort of a pointer to one.That is, a function which accepts a <TT>va_list</TT> is not itself varargs,nor vice versa.</p><p>Another kludge that is sometimes used,and which sometimes works even though it is grossly nonportable,is to use a lot of <TT>int</TT> arguments,hoping that there are enough of them and that they can somehow pass through pointer, floating-point, and other arguments as well:<pre> void faterror(fmt, a1, a2, a3, a4, a5, a6) char *fmt; int a1, a2, a3, a4, a5, a6; { error(fmt, a1, a2, a3, a4, a5, a6); /* VERY WRONG */ exit(EXIT_FAILURE); }</pre>This example is presentedonly for the purpose of urging you <em>not</em> to use it;please don't try it just because you saw it here.</p><!-- aend --><p><hr><a href="funcptr.html" rev=precedes><img src="../images/buttonleft.gif" alt="prev"></a><a href="index.html" rev=subdocument><img src="../images/buttonup.gif" alt="up"></a><a href="invvarargs.html" rel=precedes><img src="../images/buttonright.gif" alt="next"></a> <a href="../questions.html"><img src="../images/buttontop.gif" alt="contents"></a><a href="../search.html"><img src="../images/buttonsrch.gif" alt="search"></a><br><!-- lastfooter --><a href="../about.html">about this FAQ list</a> <a href="../eskimo.html">about eskimo</a> <a href="../search.html">search</a> <a href="../feedback.html">feedback</a> <a href="copyright.html">copyright</a><p>Hosted by<a href="http://www.eskimo.com/"><img src="../../www.eskimo.com/img/link/eskitiny.gif" alt="Eskimo North"></a></body><!-- Mirrored from c-faq.com/varargs/handoff.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:59:00 GMT --></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -