📄 extend.texi
字号:
@c Copyright (C) 1988, 1989, 1992, 1993, 1994 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 extensionsGNU C provides several language features not found in ANSI standard C.(The @samp{-pedantic} option directs GNU CC to print a warning message ifany of these features is used.) To test for the availability of thesefeatures 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 arealso available in C++. @xref{C++ Extensions,,Extensions to theC++ Language}, for extensions that apply @emph{only} to 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.* Zero Length:: Zero-length arrays.* Variable Length:: Arrays whose length is computed at run time.* Macro Varargs:: Macros with variable number of arguments.* 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.* Constructors:: Constructor expressions give structures, unions or arrays as values.* Labeled Elements:: Labeling elements of initializers.* Cast to Union:: Casting to union type from any member of the union.* Case Ranges:: `case 1 ... 9' and such.* Function Attributes:: Declaring that functions have no side effects, or that they can never return.* 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.@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.* Zero Length:: Zero-length arrays.* Variable Length:: Arrays whose length is computed at run time.* Macro Varargs:: Macros with variable number of arguments.* 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.* Constructors:: Constructor expressions give structures, unions or arrays as values.* Labeled Elements:: Labeling elements of initializers.* Cast to Union:: Casting to union type from any member of the union.* Case Ranges:: `case 1 ... 9' and such.* Function Attributes:: Declaring that functions have no side effects, or that they can never return.* 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.@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 4feb93A compound statement enclosed in parentheses may appear as an expressionin GNU C. This allows you to use loops, switches, and local variableswithin an expression.Recall that a compound statement is a sequence of statements surroundedby braces; in this construct, parentheses go around the braces. Forexample:@example(@{ int y = foo (); int z; if (y > 0) z = y; else z = - y; z; @})@end example@noindentis a valid (though slightly more complex than necessary) expressionfor the absolute value of @code{foo ()}.The last thing in the compound statement should be an expressionfollowed by a semicolon; the value of this subexpression serves as thevalue of the entire construct. (If you use some other kind of statementlast within the braces, the construct has type @code{void}, and thuseffectively no value.)This feature is especially useful in making macro definitions ``safe'' (sothat they evaluate each operand exactly once). For example, the``maximum'' function is commonly defined as a macro in standard C asfollows:@example#define max(a,b) ((a) > (b) ? (a) : (b))@end example@noindent@cindex side effects, macro argumentBut this definition computes either @var{a} or @var{b} twice, with badresults if the operand has side effects. In GNU C, if you know thetype of the operands (here let's assume @code{int}), you can definethe macro safely as follows:@example#define maxint(a,b) \ (@{int _a = (a), _b = (b); _a > _b ? _a : _b; @})@end exampleEmbedded statements are not allowed in constant expressions, such asthe value of an enumeration constant, the width of a bit field, orthe initial value of a static variable.If you don't know the type of the operand, you can still do this, but youmust use @code{typeof} (@pxref{Typeof}) or type naming (@pxref{NamingTypes}).@node Local Labels@section Locally Declared Labels@cindex local labels@cindex macros, local labelsEach statement expression is a scope in which @dfn{local labels} can bedeclared. A local label is simply an identifier; you can jump to itwith an ordinary @code{goto} statement, but only from within thestatement expression it belongs to.A local label declaration looks like this:@example__label__ @var{label};@end example@noindentor@example__label__ @var{label1}, @var{label2}, @dots{};@end exampleLocal label declarations must come at the beginning of the statementexpression, right after the @samp{(@{}, before any ordinarydeclarations.The label declaration defines the label @emph{name}, but does not definethe 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 areoften used in macros. If the macro contains nested loops, a @code{goto}can be useful for breaking out of them. However, an ordinary labelwhose scope is the whole function cannot be used: if the macro can beexpanded several times in one function, the label will be multiplydefined in that function. A local label avoids this problem. Forexample:@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 labelYou can get the address of a label defined in the current function(or a containing function) with the unary operator @samp{&&}. Thevalue has type @code{void *}. This value is a constant and can be used wherever a constant of that type is valid. For example:@examplevoid *ptr;@dots{}ptr = &&foo;@end exampleTo use these values, you need to be able to jump to one. This is donewith the computed goto statement@footnote{The analogous feature inFortran is called an assigned goto, but that name seems inappropriate inC, where one can do more than simply store label addresses in labelvariables.}, @code{goto *@var{exp};}. For example,@examplegoto *ptr;@end example@noindentAny expression of type @code{void *} is allowed.One way of using these constants is in initializing a static array thatwill serve as a jump table:@examplestatic void *array[] = @{ &&foo, &&bar, &&hack @};@end exampleThen you can select a label with indexing, like this:@examplegoto *array[i];@end example@noindentNote that this does not check whether the subscript is in bounds---arrayindexing 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, souse 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 thethreaded code for super-fast dispatching. You can use this mechanism to jump to code in a different function. Ifyou do that, totally unpredictable things will happen. The best way toavoid this is to store the label address only in automatic variables andnever pass it as an argument.@node Nested Functions@section Nested Functions@cindex nested functions@cindex downward funargs@cindex thunksA @dfn{nested function} is a function defined inside another function.(Nested functions are not supported for GNU C++.) The nested function'sname is local to the block where it is defined. For example, here wedefine a nested function named @code{square}, and call it twice:@example@groupfoo (double a, double b)@{ double square (double z) @{ return z * z; @} return square (a) + square (b);@}@end group@end exampleThe nested function can access all the variables of the containingfunction that are visible at the point of its definition. This iscalled @dfn{lexical scoping}. For example, here we show a nestedfunction which uses an inherited variable named @code{offset}:@examplebar (int *array, int offset, int size)@{ int access (int *array, int index) @{ return array[index + offset]; @} int i; @dots{} for (i = 0; i < size; i++) @dots{} access (array, i) @dots{}@}@end exampleNested function definitions are permitted within functions in the placeswhere variable definitions are allowed; that is, in any block, beforethe first statement in the block.It is possible to call the nested function from outside the scope of itsname by storing its address or passing the address to another function:@examplehack (int *array, int size)@{ void store (int index, int value) @{ array[index] = value; @} intermediate (store, size);@}@end exampleHere, the function @code{intermediate} receives the address of@code{store} as an argument. If @code{intermediate} calls @code{store},the arguments given to @code{store} are used to store into @code{array}.But this technique works only so long as the containing function(@code{hack}, in this example) does not exit.If you try to call the nested function through its address after thecontaining function has exited, all hell will break loose. If you tryto call it after a containing scope level has exited, and if it refersto some of the variables that are no longer in scope, you may be lucky,but it's not wise to take the risk. If, however, the nested functiondoes not refer to anything that has gone out of scope, you should besafe.GNU CC implements taking the address of a nested function using atechnique called @dfn{trampolines}. A paper describing them isavailable from @samp{maya.idiap.ch} in directory @file{pub/tmb},file @file{usenix88-lexic.ps.Z}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -