Chapter 2. Extensions to the C Language Family

Table of Contents
2.1. Statements and Declarations in Expressions
2.2. Locally Declared Labels
2.3. Labels as Values
2.4. Nested Functions
2.5. Constructing Function Calls
2.6. Naming an Expression's Type
2.7. Referring to a Type with typeof
2.8. Generalized Lvalues
2.9. Conditionals with Omitted Operands
2.10. Double-Word Integers
2.11. Complex Numbers
2.12. Arrays of Length Zero
2.13. Arrays of Variable Length
2.14. Macros with Variable Numbers of Arguments
2.15. Non-Lvalue Arrays May Have Subscripts
2.16. Arithmetic on void- and Function-Pointers
2.17. Non-Constant Initializers
2.18. Constructor Expressions
2.19. Labeled Elements in Initializers
2.20. Case Ranges
2.21. Cast to a Union Type
2.22. Declaring Attributes of Functions
2.23. Prototypes and Old-Style Function Definitions
2.24. C++ Style Comments
2.25. Dollar Signs in Identifier Names
2.26. The Escape Character in Constants
2.27. Inquiring on Alignment of Types or Variables
2.28. Specifying Attributes of Variables
2.29. Specifying Attributes of Types
2.30. An Inline Function is As Fast As a Macro
2.31. Assembler Instructions with C Expression Operands
2.32. Constraints for asm Operands
2.33. Controlling Names Used in Assembler Code
2.34. Variables in Specified Registers
2.35. Alternate Keywords
2.36. Incomplete enum Types
2.37. Function Names as Strings
2.38. Getting the Return or Frame Address of a Function

GNU C provides several language features not found in ANSI standard C. (The -pedantic option directs the compiler to print a warning message if any of these features is used.) To test for the availability of these features in conditional compilation, check for a predefined macro __GNUC__, which is always defined under the compiler.

All these extensions are available in C. Most of them are also available in C++. See Chapter 3, for extensions that apply only to C++.

2.1. 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 (see Section 2.7.) or type naming (see Section 2.6.).