您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

239 行
10KB

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- Copyright (C) 1988-2020 Free Software Foundation, Inc.
  4. Permission is granted to copy, distribute and/or modify this document
  5. under the terms of the GNU Free Documentation License, Version 1.3 or
  6. any later version published by the Free Software Foundation; with the
  7. Invariant Sections being "Funding Free Software", the Front-Cover
  8. Texts being (a) (see below), and with the Back-Cover Texts being (b)
  9. (see below). A copy of the license is included in the section entitled
  10. "GNU Free Documentation License".
  11. (a) The FSF's Front-Cover Text is:
  12. A GNU Manual
  13. (b) The FSF's Back-Cover Text is:
  14. You have freedom to copy and modify this GNU Manual, like GNU
  15. software. Copies published by the Free Software Foundation raise
  16. funds for GNU development. -->
  17. <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
  18. <head>
  19. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  20. <title>Statement Exprs (Using the GNU Compiler Collection (GCC))</title>
  21. <meta name="description" content="Statement Exprs (Using the GNU Compiler Collection (GCC))">
  22. <meta name="keywords" content="Statement Exprs (Using the GNU Compiler Collection (GCC))">
  23. <meta name="resource-type" content="document">
  24. <meta name="distribution" content="global">
  25. <meta name="Generator" content="makeinfo">
  26. <link href="index.html#Top" rel="start" title="Top">
  27. <link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
  28. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  29. <link href="C-Extensions.html#C-Extensions" rel="up" title="C Extensions">
  30. <link href="Local-Labels.html#Local-Labels" rel="next" title="Local Labels">
  31. <link href="C-Extensions.html#C-Extensions" rel="prev" title="C Extensions">
  32. <style type="text/css">
  33. <!--
  34. a.summary-letter {text-decoration: none}
  35. blockquote.indentedblock {margin-right: 0em}
  36. blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
  37. blockquote.smallquotation {font-size: smaller}
  38. div.display {margin-left: 3.2em}
  39. div.example {margin-left: 3.2em}
  40. div.lisp {margin-left: 3.2em}
  41. div.smalldisplay {margin-left: 3.2em}
  42. div.smallexample {margin-left: 3.2em}
  43. div.smalllisp {margin-left: 3.2em}
  44. kbd {font-style: oblique}
  45. pre.display {font-family: inherit}
  46. pre.format {font-family: inherit}
  47. pre.menu-comment {font-family: serif}
  48. pre.menu-preformatted {font-family: serif}
  49. pre.smalldisplay {font-family: inherit; font-size: smaller}
  50. pre.smallexample {font-size: smaller}
  51. pre.smallformat {font-family: inherit; font-size: smaller}
  52. pre.smalllisp {font-size: smaller}
  53. span.nolinebreak {white-space: nowrap}
  54. span.roman {font-family: initial; font-weight: normal}
  55. span.sansserif {font-family: sans-serif; font-weight: normal}
  56. ul.no-bullet {list-style: none}
  57. -->
  58. </style>
  59. </head>
  60. <body lang="en">
  61. <a name="Statement-Exprs"></a>
  62. <div class="header">
  63. <p>
  64. Next: <a href="Local-Labels.html#Local-Labels" accesskey="n" rel="next">Local Labels</a>, Up: <a href="C-Extensions.html#C-Extensions" accesskey="u" rel="up">C Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
  65. </div>
  66. <hr>
  67. <a name="Statements-and-Declarations-in-Expressions"></a>
  68. <h3 class="section">6.1 Statements and Declarations in Expressions</h3>
  69. <a name="index-statements-inside-expressions"></a>
  70. <a name="index-declarations-inside-expressions"></a>
  71. <a name="index-expressions-containing-statements"></a>
  72. <a name="index-macros_002c-statements-in-expressions"></a>
  73. <p>A compound statement enclosed in parentheses may appear as an expression
  74. in GNU C. This allows you to use loops, switches, and local variables
  75. within an expression.
  76. </p>
  77. <p>Recall that a compound statement is a sequence of statements surrounded
  78. by braces; in this construct, parentheses go around the braces. For
  79. example:
  80. </p>
  81. <div class="smallexample">
  82. <pre class="smallexample">({ int y = foo (); int z;
  83. if (y &gt; 0) z = y;
  84. else z = - y;
  85. z; })
  86. </pre></div>
  87. <p>is a valid (though slightly more complex than necessary) expression
  88. for the absolute value of <code>foo ()</code>.
  89. </p>
  90. <p>The last thing in the compound statement should be an expression
  91. followed by a semicolon; the value of this subexpression serves as the
  92. value of the entire construct. (If you use some other kind of statement
  93. last within the braces, the construct has type <code>void</code>, and thus
  94. effectively no value.)
  95. </p>
  96. <p>This feature is especially useful in making macro definitions &ldquo;safe&rdquo; (so
  97. that they evaluate each operand exactly once). For example, the
  98. &ldquo;maximum&rdquo; function is commonly defined as a macro in standard C as
  99. follows:
  100. </p>
  101. <div class="smallexample">
  102. <pre class="smallexample">#define max(a,b) ((a) &gt; (b) ? (a) : (b))
  103. </pre></div>
  104. <p><a name="index-side-effects_002c-macro-argument"></a>
  105. But this definition computes either <var>a</var> or <var>b</var> twice, with bad
  106. results if the operand has side effects. In GNU C, if you know the
  107. type of the operands (here taken as <code>int</code>), you can avoid this
  108. problem by defining the macro as follows:
  109. </p>
  110. <div class="smallexample">
  111. <pre class="smallexample">#define maxint(a,b) \
  112. ({int _a = (a), _b = (b); _a &gt; _b ? _a : _b; })
  113. </pre></div>
  114. <p>Note that introducing variable declarations (as we do in <code>maxint</code>) can
  115. cause variable shadowing, so while this example using the <code>max</code> macro
  116. produces correct results:
  117. </p><div class="smallexample">
  118. <pre class="smallexample">int _a = 1, _b = 2, c;
  119. c = max (_a, _b);
  120. </pre></div>
  121. <p>this example using maxint will not:
  122. </p><div class="smallexample">
  123. <pre class="smallexample">int _a = 1, _b = 2, c;
  124. c = maxint (_a, _b);
  125. </pre></div>
  126. <p>This problem may for instance occur when we use this pattern recursively, like
  127. so:
  128. </p>
  129. <div class="smallexample">
  130. <pre class="smallexample">#define maxint3(a, b, c) \
  131. ({int _a = (a), _b = (b), _c = (c); maxint (maxint (_a, _b), _c); })
  132. </pre></div>
  133. <p>Embedded statements are not allowed in constant expressions, such as
  134. the value of an enumeration constant, the width of a bit-field, or
  135. the initial value of a static variable.
  136. </p>
  137. <p>If you don&rsquo;t know the type of the operand, you can still do this, but you
  138. must use <code>typeof</code> or <code>__auto_type</code> (see <a href="Typeof.html#Typeof">Typeof</a>).
  139. </p>
  140. <p>In G++, the result value of a statement expression undergoes array and
  141. function pointer decay, and is returned by value to the enclosing
  142. expression. For instance, if <code>A</code> is a class, then
  143. </p>
  144. <div class="smallexample">
  145. <pre class="smallexample"> A a;
  146. ({a;}).Foo ()
  147. </pre></div>
  148. <p>constructs a temporary <code>A</code> object to hold the result of the
  149. statement expression, and that is used to invoke <code>Foo</code>.
  150. Therefore the <code>this</code> pointer observed by <code>Foo</code> is not the
  151. address of <code>a</code>.
  152. </p>
  153. <p>In a statement expression, any temporaries created within a statement
  154. are destroyed at that statement&rsquo;s end. This makes statement
  155. expressions inside macros slightly different from function calls. In
  156. the latter case temporaries introduced during argument evaluation are
  157. destroyed at the end of the statement that includes the function
  158. call. In the statement expression case they are destroyed during
  159. the statement expression. For instance,
  160. </p>
  161. <div class="smallexample">
  162. <pre class="smallexample">#define macro(a) ({__typeof__(a) b = (a); b + 3; })
  163. template&lt;typename T&gt; T function(T a) { T b = a; return b + 3; }
  164. void foo ()
  165. {
  166. macro (X ());
  167. function (X ());
  168. }
  169. </pre></div>
  170. <p>has different places where temporaries are destroyed. For the
  171. <code>macro</code> case, the temporary <code>X</code> is destroyed just after
  172. the initialization of <code>b</code>. In the <code>function</code> case that
  173. temporary is destroyed when the function returns.
  174. </p>
  175. <p>These considerations mean that it is probably a bad idea to use
  176. statement expressions of this form in header files that are designed to
  177. work with C++. (Note that some versions of the GNU C Library contained
  178. header files using statement expressions that lead to precisely this
  179. bug.)
  180. </p>
  181. <p>Jumping into a statement expression with <code>goto</code> or using a
  182. <code>switch</code> statement outside the statement expression with a
  183. <code>case</code> or <code>default</code> label inside the statement expression is
  184. not permitted. Jumping into a statement expression with a computed
  185. <code>goto</code> (see <a href="Labels-as-Values.html#Labels-as-Values">Labels as Values</a>) has undefined behavior.
  186. Jumping out of a statement expression is permitted, but if the
  187. statement expression is part of a larger expression then it is
  188. unspecified which other subexpressions of that expression have been
  189. evaluated except where the language definition requires certain
  190. subexpressions to be evaluated before or after the statement
  191. expression. A <code>break</code> or <code>continue</code> statement inside of
  192. a statement expression used in <code>while</code>, <code>do</code> or <code>for</code>
  193. loop or <code>switch</code> statement condition
  194. or <code>for</code> statement init or increment expressions jumps to an
  195. outer loop or <code>switch</code> statement if any (otherwise it is an error),
  196. rather than to the loop or <code>switch</code> statement in whose condition
  197. or init or increment expression it appears.
  198. In any case, as with a function call, the evaluation of a
  199. statement expression is not interleaved with the evaluation of other
  200. parts of the containing expression. For example,
  201. </p>
  202. <div class="smallexample">
  203. <pre class="smallexample"> foo (), (({ bar1 (); goto a; 0; }) + bar2 ()), baz();
  204. </pre></div>
  205. <p>calls <code>foo</code> and <code>bar1</code> and does not call <code>baz</code> but
  206. may or may not call <code>bar2</code>. If <code>bar2</code> is called, it is
  207. called after <code>foo</code> and before <code>bar1</code>.
  208. </p>
  209. <hr>
  210. <div class="header">
  211. <p>
  212. Next: <a href="Local-Labels.html#Local-Labels" accesskey="n" rel="next">Local Labels</a>, Up: <a href="C-Extensions.html#C-Extensions" accesskey="u" rel="up">C Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
  213. </div>
  214. </body>
  215. </html>