⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 library_28.html

📁 Linux程序员的工作手册
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<!-- This HTML file has been created by texi2html 1.27     from library.texinfo on 3 March 1994 --><TITLE>The GNU C Library - C Language Facilities Implemented By the Library</TITLE><P>Go to the <A HREF="library_27.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_27.html">previous</A>, <A HREF="library_29.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_29.html">next</A> section.<P><H1><A NAME="SEC470" HREF="library_toc.html#SEC470" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC470">C Language Facilities Implemented By the Library</A></H1><P>Some of the facilities implemented by the C library really should bethought of as parts of the C language itself.  These facilities ought tobe documented in the C Language Manual, not in the library manual; butsince we don't have the language manual yet, and documentation for thesefeatures has been written, we are publishing it here.<P><A NAME="IDX1916"></A><A NAME="IDX1917"></A><A NAME="IDX1918"></A><H2><A NAME="SEC471" HREF="library_toc.html#SEC471" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC471">Explicitly Checking Internal Consistency</A></H2><P>When you're writing a program, it's often a good idea to put in checksat strategic places for "impossible" errors or violations of basicassumptions.  These checks are helpful in debugging problems due tomisunderstandings between different parts of the program.<A NAME="IDX1919"></A><P>The <CODE>assert</CODE> macro, defined in the header file <TT>`assert.h'</TT>,provides a convenient way to abort the program while printing a messageabout where in the program the error was detected.<A NAME="IDX1920"></A><P>Once you think your program is debugged, you can disable the errorchecks performed by the <CODE>assert</CODE> macro by recompiling with themacro <CODE>NDEBUG</CODE> defined.  This means you don't actually have tochange the program source code to disable these checks.<P>But disabling these consistency checks is undesirable unless they makethe program significantly slower.  All else being equal, more errorchecking is good no matter who is running the program.  A wise userwould rather have a program crash, visibly, than have it return nonsensewithout indicating anything might be wrong.<P><A NAME="IDX1921"></A><U>Macro:</U> void <B>assert</B> <I>(int <VAR>expression</VAR>)</I><P>Verify the programmer's belief that <VAR>expression</VAR> should be nonzeroat this point in the program.<P>If <CODE>NDEBUG</CODE> is not defined, <CODE>assert</CODE> tests the value of<VAR>expression</VAR>.  If it is false (zero), <CODE>assert</CODE> aborts theprogram (see section <A HREF="library_22.html#SEC399" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_22.html#SEC399">Aborting a Program</A>) after printing a message of theform:<P><PRE><TT>`<VAR>file</VAR>'</TT>:<VAR>linenum</VAR>: Assertion `<VAR>expression</VAR>' failed.</PRE><P>on the standard error stream <CODE>stderr</CODE> (see section <A HREF="library_11.html#SEC119" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_11.html#SEC119">Standard Streams</A>).The filename and line number are taken from the C preprocessor macros<CODE>__FILE__</CODE> and <CODE>__LINE__</CODE> and specify where the call to<CODE>assert</CODE> was written.<P>If the preprocessor macro <CODE>NDEBUG</CODE> is defined at the point where<TT>`assert.h'</TT> is included, the <CODE>assert</CODE> macro is defined to doabsolutely nothing.<P><STRONG>Warning:</STRONG> Even the argument expression <VAR>expression</VAR> is notevaluated if <CODE>NDEBUG</CODE> is in effect.  So never use <CODE>assert</CODE>with arguments that involve side effects.  For example, <CODE>assert(++i &#62; 0);</CODE> is a bad idea, because <CODE>i</CODE> will not be incremented if<CODE>NDEBUG</CODE> is defined.<P><STRONG>Usage note:</STRONG> The <CODE>assert</CODE> facility is designed fordetecting <EM>internal inconsistency</EM>; it is not suitable forreporting invalid input or improper usage by <EM>the user</EM> of theprogram.<P>The information in the diagnostic messages printed by the <CODE>assert</CODE>macro is intended to help you, the programmer, track down the cause of abug, but is not really useful for telling a user of your program why hisor her input was invalid or why a command could not be carried out.  Soyou can't use <CODE>assert</CODE> to print the error messages for theseeventualities.<P>What's more, your program should not abort when given invalid input, as<CODE>assert</CODE> would do--it should exit with nonzero status (see section <A HREF="library_22.html#SEC397" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_22.html#SEC397">Exit Status</A>) after printing its error messages, or perhaps read anothercommand or move on to the next input file.<P>See section <A HREF="library_2.html#SEC17" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_2.html#SEC17">Error Messages</A>, for information on printing error messages forproblems that <EM>do not</EM> represent bugs in the program.<P><A NAME="IDX1922"></A><A NAME="IDX1923"></A><A NAME="IDX1924"></A><H2><A NAME="SEC472" HREF="library_toc.html#SEC472" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC472">Variadic Functions</A></H2><P>ANSI C defines a syntax for declaring a function to take a variablenumber or type of arguments.  (Such functions are referred to as<DFN>varargs functions</DFN> or <DFN>variadic functions</DFN>.)  However, thelanguage itself provides no mechanism for such functions to access theirnon-required arguments; instead, you use the variable arguments macrosdefined in <TT>`stdarg.h'</TT>.<P>This section describes how to declare variadic functions, how to writethem, and how to call them properly.<P><STRONG>Compatibility Note:</STRONG> Many older C dialects provide a similar,but incompatible, mechanism for defining functions with variable numbersof arguments, using <TT>`varargs.h'</TT>.<P><H3><A NAME="SEC473" HREF="library_toc.html#SEC473" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC473">Why Variadic Functions are Used</A></H3><P>Ordinary C functions take a fixed number of arguments.  When you definea function, you specify the data type for each argument.  Every call tothe function should supply the expected number of arguments, with typesthat can be converted to the specified ones.  Thus, if the function<SAMP>`foo'</SAMP> is declared with <CODE>int foo (int, char *);</CODE> then you mustcall it with two arguments, a number (any kind will do) and a stringpointer.<P>But some functions perform operations that can meaningfully accept anunlimited number of arguments.<P>In some cases a function can handle any number of values by operating onall of them as a block.  For example, consider a function that allocatesa one-dimensional array with <CODE>malloc</CODE> to hold a specified set ofvalues.  This operation makes sense for any number of values, as long asthe length of the array corresponds to that number.  Without facilitiesfor variable arguments, you would have to define a separate function foreach possible array size.<P>The library function <CODE>printf</CODE> (see section <A HREF="library_11.html#SEC128" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_11.html#SEC128">Formatted Output</A>) is anexample of another class of function where variable arguments areuseful.  This function prints its arguments (which can vary in type aswell as number) under the control of a format template string.<P>These are good reasons to define a <DFN>variadic</DFN> function which canhandle as many arguments as the caller chooses to pass.<P>Some functions such as <CODE>open</CODE> take a fixed set of arguments, butoccasionally ignore the last few.  Strict adherence to ANSI C requiresthese functions to be defined as variadic; in practice, however, the GNUC compiler and most other C compilers let you define such a function totake a fixed set of arguments--the most it can ever use--and then only<EM>declare</EM> the function as variadic (or not declare its argumentsat all!).<P><H3><A NAME="SEC474" HREF="library_toc.html#SEC474" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC474">How Variadic Functions are Defined and Used</A></H3><P>Defining and using a variadic function involves three steps:<P><UL><LI><EM>Define</EM> the function as variadic, using an ellipsis(<SAMP>`...'</SAMP>) in the argument list, and using special macros toaccess the variable arguments.  See section <A HREF="library_28.html#SEC476" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC476">Receiving the Argument Values</A>.<P><LI><EM>Declare</EM> the function as variadic, using a prototype with anellipsis (<SAMP>`...'</SAMP>), in all the files which call it.See section <A HREF="library_28.html#SEC475" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC475">Syntax for Variable Arguments</A>.<P><LI><EM>Call</EM> the function by writing the fixed arguments followed by theadditional variable arguments.  See section <A HREF="library_28.html#SEC478" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC478">Calling Variadic Functions</A>.</UL><P><A NAME="IDX1925"></A><A NAME="IDX1926"></A><A NAME="IDX1927"></A><H4><A NAME="SEC475" HREF="library_toc.html#SEC475" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC475">Syntax for Variable Arguments</A></H4><P>A function that accepts a variable number of arguments must be declaredwith a prototype that says so.   You write the fixed arguments as usual,and then tack on <SAMP>`...'</SAMP> to indicate the possibility of additional arguments.  The syntax of ANSI C requires at least one fixedargument before the <SAMP>`...'</SAMP>.  For example,<P><PRE>int func (const char *a, int b, ...){  ...}	</PRE><P>outlines a definition of a function <CODE>func</CODE> which returns an<CODE>int</CODE> and takes two required arguments, a <CODE>const char *</CODE> andan <CODE>int</CODE>.  These are followed by any number of anonymousarguments.<P><STRONG>Portability note:</STRONG> For some C compilers, the last requiredargument must not be declared <CODE>register</CODE> in the functiondefinition.  Furthermore, this argument's type must be<DFN>self-promoting</DFN>: that is, the default promotions must not changeits type.  This rules out array and function types, as well as<CODE>float</CODE>, <CODE>char</CODE> (whether signed or not) and <CODE>short int</CODE>(whether signed or not).  This is actually an ANSI C requirement.<P><A NAME="IDX1928"></A><A NAME="IDX1929"></A><H4><A NAME="SEC476" HREF="library_toc.html#SEC476" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC476">Receiving the Argument Values</A></H4><P>Ordinary fixed arguments have individual names, and you can use thesenames to access their values.  But optional arguments have nonames--nothing but <SAMP>`...'</SAMP>.  How can you access them?<A NAME="IDX1930"></A><P>The only way to access them is sequentially, in the order they werewritten, and you must use special macros from <TT>`stdarg.h'</TT> in thefollowing three step process:<P><OL><LI>You initialize an argument pointer variable of type <CODE>va_list</CODE> using<CODE>va_start</CODE>.  The argument pointer when initialized points to thefirst optional argument.<P><LI>You access the optional arguments by successive calls to <CODE>va_arg</CODE>.The first call to <CODE>va_arg</CODE> gives you the first optional argument,the next call gives you the second, and so on.<P>You can stop at any time if you wish to ignore any remaining optionalarguments.  It is perfectly all right for a function to access fewerarguments than were supplied in the call, but you will get garbagevalues if you try to access too many arguments.<P><LI>You indicate that you are finished with the argument pointer variable bycalling <CODE>va_end</CODE>.<P>(In practice, with most C compilers, calling <CODE>va_end</CODE> does nothingand you do not really need to call it.  This is always true in the GNU Ccompiler.  But you might as well call <CODE>va_end</CODE> just in case yourprogram is someday compiled with a peculiar compiler.)</OL><P>See section <A HREF="library_28.html#SEC479" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_28.html#SEC479">Argument Access Macros</A>, for the full definitions of <CODE>va_start</CODE>, <CODE>va_arg</CODE> and <CODE>va_end</CODE>.<P>Steps 1 and 3 must be performed in the function that accepts theoptional arguments.  However, you can pass the <CODE>va_list</CODE> variableas an argument to another function and perform all or part of step 2there.<P>You can perform the entire sequence of the three steps multiple timeswithin a single function invocation.  If you want to ignore the optionalarguments, you can do these steps zero times.<P>You can have more than one argument pointer variable if you like.  Youcan initialize each variable with <CODE>va_start</CODE> when you wish, andthen you can fetch arguments with each argument pointer as you wish.Each argument pointer variable will sequence through the same set ofargument values, but at its own pace.<P><STRONG>Portability note:</STRONG> With some compilers, once you pass anargument pointer value to a subroutine, you must not keep using the sameargument pointer value after that subroutine returns.  For fullportability, you should just pass it to <CODE>va_end</CODE>.  This is actuallyan ANSI C requirement, but most ANSI C compilers work happilyregardless.<P><A NAME="IDX1931"></A><A NAME="IDX1932"></A><A NAME="IDX1933"></A><H4><A NAME="SEC477" HREF="library_toc.html#SEC477" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC477">How Many Arguments Were Supplied</A></H4><P>There is no general way for a function to determine the number and typeof the optional arguments it was called with.  So whoever designs the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -