⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extend.texi

📁 GCC
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
@c Copyright (C) 1988,1989,1992,1993,1994,1996,1998,1999,2000,2001 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.

@node C Extensions
@chapter Extensions to the C Language Family
@cindex extensions, C language
@cindex C language extensions

@opindex pedantic
GNU C provides several language features not found in ISO standard C.
(The @option{-pedantic} option directs GNU CC 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
@code{__GNUC__}, which is always defined under GNU CC.

These extensions are available in C and Objective C.  Most of them are
also available in C++.  @xref{C++ Extensions,,Extensions to the
C++ Language}, for extensions that apply @emph{only} to C++.

Some features that are in ISO C99 but not C89 or C++ are also, as
extensions, accepted by GCC in C89 mode and in C++.

@c The only difference between the two versions of this menu is that the
@c version for clear INTERNALS has an extra node, "Constraints" (which
@c appears in a separate chapter in the other version of the manual).
@ifset INTERNALS
@menu
* Statement Exprs::     Putting statements and declarations inside expressions.
* Local Labels::        Labels local to a statement-expression.
* Labels as Values::    Getting pointers to labels, and computed gotos.
* Nested Functions::    As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls::	Dispatching a call to another function.
* Naming Types::        Giving a name to the type of some expression.
* Typeof::              @code{typeof}: referring to the type of an expression.
* Lvalues::             Using @samp{?:}, @samp{,} and casts in lvalues.
* Conditionals::        Omitting the middle operand of a @samp{?:} expression.
* Long Long::		Double-word integers---@code{long long int}.
* Complex::             Data types for complex numbers.
* Hex Floats::          Hexadecimal floating-point constants.
* Zero Length::         Zero-length arrays.
* Variable Length::     Arrays whose length is computed at run time.
* Variadic Macros::	Macros with a variable number of arguments.
* Escaped Newlines::    Slightly looser rules for escaped newlines.
* Multi-line Strings::  String literals with embedded newlines.
* Subscripting::        Any array can be subscripted, even if not an lvalue.
* Pointer Arith::       Arithmetic on @code{void}-pointers and function pointers.
* Initializers::        Non-constant initializers.
* Compound Literals::   Compound literals give structures, unions
                         or arrays as values.
* Designated Inits::	Labeling elements of initializers.
* Cast to Union::       Casting to union type from any member of the union.
* Case Ranges::		`case 1 ... 9' and such.
* Mixed Declarations::	Mixing declarations and code.
* Function Attributes:: Declaring that functions have no side effects,
                         or that they can never return.
* Attribute Syntax::    Formal syntax for attributes.
* Function Prototypes:: Prototype declarations and old-style definitions.
* C++ Comments::        C++ comments are recognized.
* Dollar Signs::        Dollar sign is allowed in identifiers.
* Character Escapes::   @samp{\e} stands for the character @key{ESC}.
* Variable Attributes::	Specifying attributes of variables.
* Type Attributes::	Specifying attributes of types.
* Alignment::           Inquiring about the alignment of a type or variable.
* Inline::              Defining inline functions (as fast as macros).
* Extended Asm::        Assembler instructions with C expressions as operands.
                         (With them you can define ``built-in'' functions.)
* Asm Labels::          Specifying the assembler name to use for a C symbol.
* Explicit Reg Vars::   Defining variables residing in specified registers.
* Alternate Keywords::  @code{__const__}, @code{__asm__}, etc., for header files.
* Incomplete Enums::    @code{enum foo;}, with details to follow.
* Function Names::	Printable strings which are the name of the current
			 function.
* Return Address::      Getting the return or frame address of a function.
* Other Builtins::      Other built-in functions.
@end menu
@end ifset
@ifclear INTERNALS
@menu
* Statement Exprs::     Putting statements and declarations inside expressions.
* Local Labels::        Labels local to a statement-expression.
* Labels as Values::    Getting pointers to labels, and computed gotos.
* Nested Functions::    As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls::	Dispatching a call to another function.
* Naming Types::        Giving a name to the type of some expression.
* Typeof::              @code{typeof}: referring to the type of an expression.
* Lvalues::             Using @samp{?:}, @samp{,} and casts in lvalues.
* Conditionals::        Omitting the middle operand of a @samp{?:} expression.
* Long Long::		Double-word integers---@code{long long int}.
* Complex::             Data types for complex numbers.
* Hex Floats::          Hexadecimal floating-point constants.
* Zero Length::         Zero-length arrays.
* Variable Length::     Arrays whose length is computed at run time.
* Variadic Macros::	Macros with a variable number of arguments.
* Escaped Newlines::    Slightly looser rules for escaped newlines.
* Multi-line Strings::  String literals with embedded newlines.
* Subscripting::        Any array can be subscripted, even if not an lvalue.
* Pointer Arith::       Arithmetic on @code{void}-pointers and function pointers.
* Initializers::        Non-constant initializers.
* Compound Literals::   Compound literals give structures, unions
                         or arrays as values.
* Designated Inits::	Labeling elements of initializers.
* Cast to Union::       Casting to union type from any member of the union.
* Case Ranges::		`case 1 ... 9' and such.
* Mixed Declarations::	Mixing declarations and code.
* Function Attributes:: Declaring that functions have no side effects,
                         or that they can never return.
* Attribute Syntax::    Formal syntax for attributes.
* Function Prototypes:: Prototype declarations and old-style definitions.
* C++ Comments::        C++ comments are recognized.
* Dollar Signs::        Dollar sign is allowed in identifiers.
* Character Escapes::   @samp{\e} stands for the character @key{ESC}.
* Variable Attributes::	Specifying attributes of variables.
* Type Attributes::	Specifying attributes of types.
* Alignment::           Inquiring about the alignment of a type or variable.
* Inline::              Defining inline functions (as fast as macros).
* Extended Asm::        Assembler instructions with C expressions as operands.
                         (With them you can define ``built-in'' functions.)
* Constraints::         Constraints for asm operands
* Asm Labels::          Specifying the assembler name to use for a C symbol.
* Explicit Reg Vars::   Defining variables residing in specified registers.
* Alternate Keywords::  @code{__const__}, @code{__asm__}, etc., for header files.
* Incomplete Enums::    @code{enum foo;}, with details to follow.
* Function Names::	Printable strings which are the name of the current
			 function.
* Return Address::      Getting the return or frame address of a function.
* Other Builtins::      Other built-in functions.
@end menu
@end ifclear

@node Statement Exprs
@section Statements and Declarations in Expressions
@cindex statements inside expressions
@cindex declarations inside expressions
@cindex expressions containing statements
@cindex macros, statements in expressions

@c the above section title wrapped and causes an underfull hbox.. i
@c changed it from "within" to "in". --mew 4feb93

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:

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

@noindent
is a valid (though slightly more complex than necessary) expression
for the absolute value of @code{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 @code{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:

@example
#define max(a,b) ((a) > (b) ? (a) : (b))
@end example

@noindent
@cindex side effects, macro argument
But this definition computes either @var{a} or @var{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 @code{int}), you can define
the macro safely as follows:

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

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 @code{typeof} (@pxref{Typeof}) or type naming (@pxref{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:

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

@noindent
does not work the same way as:

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

@noindent
In particular, if the expression passed into @code{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.)

@node Local Labels
@section Locally Declared Labels
@cindex local labels
@cindex macros, local labels

Each statement expression is a scope in which @dfn{local labels} can be
declared.  A local label is simply an identifier; you can jump to it
with an ordinary @code{goto} statement, but only from within the
statement expression it belongs to.

A local label declaration looks like this:

@example
__label__ @var{label};
@end example

@noindent
or

@example
__label__ @var{label1}, @var{label2}, @dots{};
@end example

Local label declarations must come at the beginning of the statement
expression, right after the @samp{(@{}, before any ordinary
declarations.

The label declaration defines the label @emph{name}, but does not define
the label itself.  You must do this in the usual way, with
@code{@var{label}:}, within the statements of the statement expression.

The local label feature is useful because statement expressions are
often used in macros.  If the macro contains nested loops, a @code{goto}
can be useful for breaking out of them.  However, an ordinary label
whose scope is the whole function cannot be used: if the macro can be
expanded several times in one function, the label will be multiply
defined in that function.  A local label avoids this problem.  For
example:

@example
#define SEARCH(array, target)                     \
(@{                                                \
  __label__ found;                                \
  typeof (target) _SEARCH_target = (target);      \
  typeof (*(array)) *_SEARCH_array = (array);     \
  int i, j;                                       \
  int value;                                      \
  for (i = 0; i < max; i++)                       \
    for (j = 0; j < max; j++)                     \
      if (_SEARCH_array[i][j] == _SEARCH_target)  \
        @{ value = i; goto found; @}                \
  value = -1;                                     \
 found:                                           \
  value;                                          \
@})
@end example

@node Labels as Values
@section Labels as Values
@cindex labels as values
@cindex computed gotos
@cindex goto with computed label
@cindex address of a label

You can get the address of a label defined in the current function
(or a containing function) with the unary operator @samp{&&}.  The
value has type @code{void *}.  This value is a constant and can be used
wherever a constant of that type is valid.  For example:

@example
void *ptr;
@dots{}
ptr = &&foo;
@end example

To use these values, you need to be able to jump to one.  This is done
with the computed goto statement@footnote{The analogous feature in
Fortran is called an assigned goto, but that name seems inappropriate in
C, where one can do more than simply store label addresses in label
variables.}, @code{goto *@var{exp};}.  For example,

@example
goto *ptr;
@end example

@noindent
Any expression of type @code{void *} is allowed.

One way of using these constants is in initializing a static array that
will serve as a jump table:

@example
static void *array[] = @{ &&foo, &&bar, &&hack @};
@end example

Then you can select a label with indexing, like this:

@example
goto *array[i];
@end example

@noindent
Note that this does not check whether the subscript is in bounds---array
indexing in C never does that.

Such an array of label values serves a purpose much like that of the
@code{switch} statement.  The @code{switch} statement is cleaner, so
use that rather than an array unless the problem does not fit a
@code{switch} statement very well.

Another use of label values is in an interpreter for threaded code.
The labels within the interpreter function can be stored in the
threaded code for super-fast dispatching.

You may not use this mechanism to jump to code in a different function.
If you do that, totally unpredictable things will happen.  The best way to
avoid this is to store the label address only in automatic variables and
never pass it as an argument.

An alternate way to write the above example is

@example
static const int array[] = @{ &&foo - &&foo, &&bar - &&foo,
                             &&hack - &&foo @};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -