📄 cpp.html
字号:
<PRE>do { if (x == 0) \ fprintf (stderr, "Warning: x == 0\n"); } \while (0)</PRE><P>Stringification in C involves more than putting doublequote charactersaround the fragment; it is necessary to put backslashes in front of alldoublequote characters, and all backslashes in string and characterconstants, in order to get a valid C string constant with the propercontents. Thus, stringifying <SAMP>`p = "foo\n";'</SAMP> results in <SAMP>`"p =\"foo\\n\";"'</SAMP>. However, backslashes that are not inside of string orcharacter constants are not duplicated: <SAMP>`\n'</SAMP> by itself stringifies to<SAMP>`"\n"'</SAMP>.</P><P>Whitespace (including comments) in the text being stringified is handledaccording to precise rules. All leading and trailing whitespace is ignored.Any sequence of whitespace in the middle of the text is converted toa single space in the stringified result.</P><H3><A NAME="SEC16" HREF="cpp_toc.html#TOC16">Concatenation</A></H3><P><A NAME="IDX55"></A><A NAME="IDX56"></A><EM>Concatenation</EM> means joining two strings into one. In the contextof macro expansion, concatenation refers to joining two lexical unitsinto one longer one. Specifically, an actual argument to the macro can beconcatenated with another actual argument or with fixed text to producea longer name. The longer name might be the name of a function,variable or type, or a C keyword; it might even be the name of anothermacro, in which case it will be expanded.</P><P>When you define a macro, you request concatenation with the specialoperator <SAMP>`##'</SAMP> in the macro body. When the macro is called,after actual arguments are substituted, all <SAMP>`##'</SAMP> operators aredeleted, and so is any whitespace next to them (including whitespacethat was part of an actual argument). The result is to concatenatethe syntactic tokens on either side of the <SAMP>`##'</SAMP>.</P><P>Consider a C program that interprets named commands. There probably needsto be a table of commands, perhaps an array of structures declared asfollows:</P><PRE>struct command{ char *name; void (*function) ();};struct command commands[] ={ { "quit", quit_command}, { "help", help_command}, ...};</PRE><P>It would be cleaner not to have to give each command name twice, once inthe string constant and once in the function name. A macro which takes thename of a command as an argument can make this unnecessary. The stringconstant can be created with stringification, and the function name byconcatenating the argument with <SAMP>`_command'</SAMP>. Here is how it is done:</P><PRE>#define COMMAND(NAME) { #NAME, NAME ## _command }struct command commands[] ={ COMMAND (quit), COMMAND (help), ...};</PRE><P>The usual case of concatenation is concatenating two names (or a name and anumber) into a longer name. But this isn't the only valid case. It isalso possible to concatenate two numbers (or a number and a name, such as<SAMP>`1.5'</SAMP> and <SAMP>`e3'</SAMP>) into a number. Also, multi-character operatorssuch as <SAMP>`+='</SAMP> can be formed by concatenation. In some cases it is evenpossible to piece together a string constant. However, two pieces of textthat don't together form a valid lexical unit cannot be concatenated. Forexample, concatenation with <SAMP>`x'</SAMP> on one side and <SAMP>`+'</SAMP> on the otheris not meaningful because those two characters can't fit together in anylexical unit of C. The ANSI standard says that such attempts atconcatenation are undefined, but in the GNU C preprocessor it is welldefined: it puts the <SAMP>`x'</SAMP> and <SAMP>`+'</SAMP> side by side with no particularspecial results.</P><P>Keep in mind that the C preprocessor converts comments to whitespace beforemacros are even considered. Therefore, you cannot create a comment byconcatenating <SAMP>`/'</SAMP> and <SAMP>`*'</SAMP>: the <SAMP>`/*'</SAMP> sequence that starts acomment is not a lexical unit, but rather the beginning of a "long" spacecharacter. Also, you can freely use comments next to a <SAMP>`##'</SAMP> in amacro definition, or in actual arguments that will be concatenated, becausethe comments will be converted to spaces at first sight, and concatenationwill later discard the spaces.</P><H3><A NAME="SEC17" HREF="cpp_toc.html#TOC17">Undefining Macros</A></H3><P><A NAME="IDX57"></A>To <EM>undefine</EM> a macro means to cancel its definition. This is donewith the <SAMP>`#undef'</SAMP> directive. <SAMP>`#undef'</SAMP> is followed by the macroname to be undefined.</P><P>Like definition, undefinition occurs at a specific point in the sourcefile, and it applies starting from that point. The name ceases to be amacro name, and from that point on it is treated by the preprocessor as ifit had never been a macro name.</P><P>For example,</P><PRE>#define FOO 4x = FOO;#undef FOOx = FOO;</PRE><P>expands into</P><PRE>x = 4;x = FOO;</PRE><P>In this example, <SAMP>`FOO'</SAMP> had better be a variable or function as wellas (temporarily) a macro, in order for the result of the expansion to bevalid C code.</P><P>The same form of <SAMP>`#undef'</SAMP> directive will cancel definitions witharguments or definitions that don't expect arguments. The <SAMP>`#undef'</SAMP>directive has no effect when used on a name not currently defined as a macro.</P><H3><A NAME="SEC18" HREF="cpp_toc.html#TOC18">Redefining Macros</A></H3><P><A NAME="IDX58"></A><EM>Redefining</EM> a macro means defining (with <SAMP>`#define'</SAMP>) a name thatis already defined as a macro.</P><P>A redefinition is trivial if the new definition is transparently identicalto the old one. You probably wouldn't deliberately write a trivialredefinition, but they can happen automatically when a header file isincluded more than once (see section <A HREF="cpp.html#SEC3">Header Files</A>), so they are acceptedsilently and without effect.</P><P>Nontrivial redefinition is considered likely to be an error, soit provokes a warning message from the preprocessor. However, sometimes itis useful to change the definition of a macro in mid-compilation. You caninhibit the warning by undefining the macro with <SAMP>`#undef'</SAMP> before thesecond definition.</P><P>In order for a redefinition to be trivial, the new definition mustexactly match the one already in effect, with two possible exceptions:</P><UL><LI>Whitespace may be added or deleted at the beginning or the end.<LI>Whitespace may be changed in the middle (but not inside strings).However, it may not be eliminated entirely, and it may not be addedwhere there was no whitespace at all.</UL><P>Recall that a comment counts as whitespace.</P><H3><A NAME="SEC19" HREF="cpp_toc.html#TOC19">Pitfalls and Subtleties of Macros</A></H3><P><A NAME="IDX59"></A><A NAME="IDX60"></A></P><P>In this section we describe some special rules that apply to macros andmacro expansion, and point out certain cases in which the rules havecounterintuitive consequences that you must watch out for.</P><H4><A NAME="SEC20" HREF="cpp_toc.html#TOC20">Improperly Nested Constructs</A></H4><P>Recall that when a macro is called with arguments, the arguments aresubstituted into the macro body and the result is checked, together withthe rest of the input file, for more macro calls.</P><P>It is possible to piece together a macro call coming partially from themacro body and partially from the actual arguments. For example,</P><PRE>#define double(x) (2*(x))#define call_with_1(x) x(1)</PRE><P>would expand <SAMP>`call_with_1 (double)'</SAMP> into <SAMP>`(2*(1))'</SAMP>.</P><P>Macro definitions do not have to have balanced parentheses. By writing anunbalanced open parenthesis in a macro body, it is possible to create amacro call that begins inside the macro body but ends outside of it. Forexample,</P><PRE>#define strange(file) fprintf (file, "%s %d",...strange(stderr) p, 35)</PRE><P>This bizarre example expands to <SAMP>`fprintf (stderr, "%s %d", p, 35)'</SAMP>!</P><H4><A NAME="SEC21" HREF="cpp_toc.html#TOC21">Unintended Grouping of Arithmetic</A></H4><P><A NAME="IDX61"></A></P><P>You may have noticed that in most of the macro definition examples shownabove, each occurrence of a macro argument name had parentheses around it.In addition, another pair of parentheses usually surround the entire macrodefinition. Here is why it is best to write macros that way.</P><P>Suppose you define a macro as follows,</P><PRE>#define ceil_div(x, y) (x + y - 1) / y</PRE><P>whose purpose is to divide, rounding up. (One use for this operation isto compute how many <SAMP>`int'</SAMP> objects are needed to hold a certainnumber of <SAMP>`char'</SAMP> objects.) Then suppose it is used as follows:</P><PRE>a = ceil_div (b & c, sizeof (int));</PRE><P>This expands into</P><PRE>a = (b & c + sizeof (int) - 1) / sizeof (int);</PRE><P>which does not do what is intended. The operator-precedence rules ofC make it equivalent to this:</P><PRE>a = (b & (c + sizeof (int) - 1)) / sizeof (int);</PRE><P>But what we want is this:</P><PRE>a = ((b & c) + sizeof (int) - 1)) / sizeof (int);</PRE><P>Defining the macro as</P><PRE>#define ceil_div(x, y) ((x) + (y) - 1) / (y)</PRE><P>provides the desired result.</P><P>However, unintended grouping can result in another way. Consider<SAMP>`sizeof ceil_div(1, 2)'</SAMP>. That has the appearance of a C expressionthat would compute the size of the type of <SAMP>`ceil_div (1, 2)'</SAMP>, but infact it means something very different. Here is what it expands to:</P><PRE>sizeof ((1) + (2) - 1) / (2)</PRE><P>This would take the size of an integer and divide it by two. The precedencerules have put the division outside the <SAMP>`sizeof'</SAMP> when it was intendedto be inside.</P><P>Parentheses around the entire macro definition can prevent such problems.Here, then, is the recommended way to define <SAMP>`ceil_div'</SAMP>:</P><PRE>#define ceil_div(x, y) (((x) + (y) - 1) / (y))</PRE><H4><A NAME="SEC22" HREF="cpp_toc.html#TOC22">Swallowing the Semicolon</A></H4><P><A NAME="IDX62"></A>Often it is desirable to define a macro that expands into a compoundstatement. Consider, for example, the following macro, that advances apointer (the argument <SAMP>`p'</SAMP> says where to find it) across whitespacecharacters:</P><PRE>#define SKIP_SPACES (p, limit) \{ register char *lim = (limit); \ while (p != lim) { \ if (*p++ != ' ') { \ p--; break; }}}</PRE><P>Here Backslash-Newline is used to split the macro definition, which mustbe a single line, so that it resembles the way such C code would belaid out if not part of a macro definition.</P><P>A call to this macro might be <SAMP>`SKIP_SPACES (p, lim)'</SAMP>. Strictlyspeaking, the call expands to a compound statement, which is a completestatement with no need for a semicolon to end it. But it looks like afunction call. So it minimizes confusion if you can use it like a functioncall, writing a semicolon afterward, as in <SAMP>`SKIP_SPACES (p, lim);'</SAMP></P><P>But this can cause trouble before <SAMP>`else'</SAMP> statements, because thesemicolon is actually a null statement. Suppose you write</P><PRE>if (*p != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -