GNU Info

Info Node: (gcc-300.info)Statement Exprs

(gcc-300.info)Statement Exprs


Next: Local Labels Up: C Extensions
Enter node , (file) or (file)node

Statements and Declarations in Expressions
==========================================

   A compound statement enclosed in parentheses may appear as an
expression in GNU C.  This allows you to use loops, switches, and local
variables within an expression.

   Recall that a compound statement is a sequence of statements
surrounded by braces; in this construct, parentheses go around the
braces.  For example:

     ({ int y = foo (); int z;
        if (y > 0) z = y;
        else z = - y;
        z; })

is a valid (though slightly more complex than necessary) expression for
the absolute value of `foo ()'.

   The last thing in the compound statement should be an expression
followed by a semicolon; the value of this subexpression serves as the
value of the entire construct.  (If you use some other kind of statement
last within the braces, the construct has type `void', and thus
effectively no value.)

   This feature is especially useful in making macro definitions "safe"
(so that they evaluate each operand exactly once).  For example, the
"maximum" function is commonly defined as a macro in standard C as
follows:

     #define max(a,b) ((a) > (b) ? (a) : (b))

But this definition computes either A or B twice, with bad results if
the operand has side effects.  In GNU C, if you know the type of the
operands (here let's assume `int'), you can define the macro safely as
follows:

     #define maxint(a,b) \
       ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

   Embedded statements are not allowed in constant expressions, such as
the value of an enumeration constant, the width of a bit-field, or the
initial value of a static variable.

   If you don't know the type of the operand, you can still do this,
but you must use `typeof' (Note: Typeof) or type naming (Note: Naming
Types).

   Statement expressions are not supported fully in G++, and their fate
there is unclear.  (It is possible that they will become fully supported
at some point, or that they will be deprecated, or that the bugs that
are present will continue to exist indefinitely.)  Presently, statement
expressions do not work well as default arguments.

   In addition, there are semantic issues with statement-expressions in
C++.  If you try to use statement-expressions instead of inline
functions in C++, you may be surprised at the way object destruction is
handled.  For example:

     #define foo(a)  ({int b = (a); b + 3; })

does not work the same way as:

     inline int foo(int a) { int b = a; return b + 3; }

In particular, if the expression passed into `foo' involves the
creation of temporaries, the destructors for those temporaries will be
run earlier in the case of the macro than in the case of the function.

   These considerations mean that it is probably a bad idea to use
statement-expressions of this form in header files that are designed to
work with C++.  (Note that some versions of the GNU C Library contained
header files using statement-expression that lead to precisely this
bug.)


automatically generated by info2www version 1.2.2.9