1<html lang="en"> 2<head> 3<title>Statement Exprs - Using the GNU Compiler Collection (GCC)</title> 4<meta http-equiv="Content-Type" content="text/html"> 5<meta name="description" content="Using the GNU Compiler Collection (GCC)"> 6<meta name="generator" content="makeinfo 4.13"> 7<link title="Top" rel="start" href="index.html#Top"> 8<link rel="up" href="C-Extensions.html#C-Extensions" title="C Extensions"> 9<link rel="next" href="Local-Labels.html#Local-Labels" title="Local Labels"> 10<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> 11<!-- 12Copyright (C) 1988-2013 Free Software Foundation, Inc. 13 14Permission is granted to copy, distribute and/or modify this document 15under the terms of the GNU Free Documentation License, Version 1.3 or 16any later version published by the Free Software Foundation; with the 17Invariant Sections being ``Funding Free Software'', the Front-Cover 18Texts being (a) (see below), and with the Back-Cover Texts being (b) 19(see below). A copy of the license is included in the section entitled 20``GNU Free Documentation License''. 21 22(a) The FSF's Front-Cover Text is: 23 24 A GNU Manual 25 26(b) The FSF's Back-Cover Text is: 27 28 You have freedom to copy and modify this GNU Manual, like GNU 29 software. Copies published by the Free Software Foundation raise 30 funds for GNU development.--> 31<meta http-equiv="Content-Style-Type" content="text/css"> 32<style type="text/css"><!-- 33 pre.display { font-family:inherit } 34 pre.format { font-family:inherit } 35 pre.smalldisplay { font-family:inherit; font-size:smaller } 36 pre.smallformat { font-family:inherit; font-size:smaller } 37 pre.smallexample { font-size:smaller } 38 pre.smalllisp { font-size:smaller } 39 span.sc { font-variant:small-caps } 40 span.roman { font-family:serif; font-weight:normal; } 41 span.sansserif { font-family:sans-serif; font-weight:normal; } 42--></style> 43<link rel="stylesheet" type="text/css" href="../cs.css"> 44</head> 45<body> 46<div class="node"> 47<a name="Statement-Exprs"></a> 48<p> 49Next: <a rel="next" accesskey="n" href="Local-Labels.html#Local-Labels">Local Labels</a>, 50Up: <a rel="up" accesskey="u" href="C-Extensions.html#C-Extensions">C Extensions</a> 51<hr> 52</div> 53 54<h3 class="section">6.1 Statements and Declarations in Expressions</h3> 55 56<p><a name="index-statements-inside-expressions-2417"></a><a name="index-declarations-inside-expressions-2418"></a><a name="index-expressions-containing-statements-2419"></a><a name="index-macros_002c-statements-in-expressions-2420"></a> 57<!-- the above section title wrapped and causes an underfull hbox.. i --> 58<!-- changed it from "within" to "in". -mew 4feb93 --> 59A compound statement enclosed in parentheses may appear as an expression 60in GNU C. This allows you to use loops, switches, and local variables 61within an expression. 62 63 <p>Recall that a compound statement is a sequence of statements surrounded 64by braces; in this construct, parentheses go around the braces. For 65example: 66 67<pre class="smallexample"> ({ int y = foo (); int z; 68 if (y > 0) z = y; 69 else z = - y; 70 z; }) 71</pre> 72 <p class="noindent">is a valid (though slightly more complex than necessary) expression 73for the absolute value of <code>foo ()</code>. 74 75 <p>The last thing in the compound statement should be an expression 76followed by a semicolon; the value of this subexpression serves as the 77value of the entire construct. (If you use some other kind of statement 78last within the braces, the construct has type <code>void</code>, and thus 79effectively no value.) 80 81 <p>This feature is especially useful in making macro definitions “safe” (so 82that they evaluate each operand exactly once). For example, the 83“maximum” function is commonly defined as a macro in standard C as 84follows: 85 86<pre class="smallexample"> #define max(a,b) ((a) > (b) ? (a) : (b)) 87</pre> 88 <p class="noindent"><a name="index-side-effects_002c-macro-argument-2421"></a>But this definition computes either <var>a</var> or <var>b</var> twice, with bad 89results if the operand has side effects. In GNU C, if you know the 90type of the operands (here taken as <code>int</code>), you can define 91the macro safely as follows: 92 93<pre class="smallexample"> #define maxint(a,b) \ 94 ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) 95</pre> 96 <p>Embedded statements are not allowed in constant expressions, such as 97the value of an enumeration constant, the width of a bit-field, or 98the initial value of a static variable. 99 100 <p>If you don't know the type of the operand, you can still do this, but you 101must use <code>typeof</code> (see <a href="Typeof.html#Typeof">Typeof</a>). 102 103 <p>In G++, the result value of a statement expression undergoes array and 104function pointer decay, and is returned by value to the enclosing 105expression. For instance, if <code>A</code> is a class, then 106 107<pre class="smallexample"> A a; 108 109 ({a;}).Foo () 110</pre> 111 <p class="noindent">constructs a temporary <code>A</code> object to hold the result of the 112statement expression, and that is used to invoke <code>Foo</code>. 113Therefore the <code>this</code> pointer observed by <code>Foo</code> is not the 114address of <code>a</code>. 115 116 <p>In a statement expression, any temporaries created within a statement 117are destroyed at that statement's end. This makes statement 118expressions inside macros slightly different from function calls. In 119the latter case temporaries introduced during argument evaluation are 120destroyed at the end of the statement that includes the function 121call. In the statement expression case they are destroyed during 122the statement expression. For instance, 123 124<pre class="smallexample"> #define macro(a) ({__typeof__(a) b = (a); b + 3; }) 125 template<typename T> T function(T a) { T b = a; return b + 3; } 126 127 void foo () 128 { 129 macro (X ()); 130 function (X ()); 131 } 132</pre> 133 <p class="noindent">has different places where temporaries are destroyed. For the 134<code>macro</code> case, the temporary <code>X</code> is destroyed just after 135the initialization of <code>b</code>. In the <code>function</code> case that 136temporary is destroyed when the function returns. 137 138 <p>These considerations mean that it is probably a bad idea to use 139statement expressions of this form in header files that are designed to 140work with C++. (Note that some versions of the GNU C Library contained 141header files using statement expressions that lead to precisely this 142bug.) 143 144 <p>Jumping into a statement expression with <code>goto</code> or using a 145<code>switch</code> statement outside the statement expression with a 146<code>case</code> or <code>default</code> label inside the statement expression is 147not permitted. Jumping into a statement expression with a computed 148<code>goto</code> (see <a href="Labels-as-Values.html#Labels-as-Values">Labels as Values</a>) has undefined behavior. 149Jumping out of a statement expression is permitted, but if the 150statement expression is part of a larger expression then it is 151unspecified which other subexpressions of that expression have been 152evaluated except where the language definition requires certain 153subexpressions to be evaluated before or after the statement 154expression. In any case, as with a function call, the evaluation of a 155statement expression is not interleaved with the evaluation of other 156parts of the containing expression. For example, 157 158<pre class="smallexample"> foo (), (({ bar1 (); goto a; 0; }) + bar2 ()), baz(); 159</pre> 160 <p class="noindent">calls <code>foo</code> and <code>bar1</code> and does not call <code>baz</code> but 161may or may not call <code>bar2</code>. If <code>bar2</code> is called, it is 162called after <code>foo</code> and before <code>bar1</code>. 163 164 </body></html> 165 166