📄 extend.texi
字号:
@c Copyright (C) 1988, 1989, 1992 Free Software Foundation, Inc.@c This is part of the GCC manual.@c For copying conditions, see the file gcc.texi.@node Extensions@chapter GNU Extensions to the C Language@cindex extensions, C language@cindex GNU extensions to the 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.@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.* 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}.* 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.* Dollar Signs:: Dollar sign is allowed in identifiers.* Character Escapes:: @samp{\e} stands for the character @key{ESC}.* Variable Attributes:: Specifying attributes of variables.* 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.@end menu@node Statement Exprs@section Statements and Declarations within Expressions@cindex statements inside expressions@cindex declarations inside expressions@cindex expressions containing statements@cindex macros, statements in expressionsA 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.The nested function's name is local to the block where it is defined.For example, here we define a nested function named @code{square},and call it twice:@examplefoo (double a, double b)@{ double square (double z) @{ return z * z; @} return square (a) + square (b);@}@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 exampleIt 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 storeinto @code{array}. But this technique works only so long as thecontaining function (@code{hack}, in this example) does not exit. Ifyou try to call the nested function through its address after thecontaining function has exited, all hell will break loose.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 the file@file{pub/tmb/usenix88-lexic.ps.Z}.A nested function can jump to a label inherited from a containingfunction, provided the label was explicitly declared in the containingfunction (@pxref{Local Labels}). Such a jump returns instantly to thecontaining function, exiting the nested function which did the@code{goto} and any intermediate functions as well. Here is an example:@examplebar (int *array, int offset, int size)@{ __label__ failure; int access (int *array, int index) @{ if (index > size) goto failure; return array[index + offset]; @} int i; @dots{} for (i = 0; i < size; i++) @dots{} access (array, i) @dots{} @dots{} return 0; /* @r{Control comes here from @code{access} if it detects an error.} */ failure: return -1;@}@end exampleA nested function always has internal linkage. Declaring one with@code{extern} is erroneous. If you need to declare the nested functionbefore its definition, use @code{auto} (which is otherwise meaninglessfor function declarations).@examplebar (int *array, int offset, int size)@{ __label__ failure; auto int access (int *, int); @dots{} int access (int *array, int index) @{ if (index > size) goto failure; return array[index + offset]; @} @dots{}@}@end example@node Naming Types@section Naming an Expression's Type@cindex naming typesYou can give a name to the type of an expression using a @code{typedef}declaration with an initializer. Here is how to define @var{name} as atype name for the type of @var{exp}:@exampletypedef @var{name} = @var{exp};@end exampleThis is useful in conjunction with the statements-within-expressionsfeature. Here is how the two together can be used to define a safe``maximum'' macro that operates on any arithmetic type:@example#define max(a,b) \ (@{typedef _ta = (a), _tb = (b); \ _ta _a = (a); _tb _b = (b); \ _a > _b ? _a : _b; @})@end example
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -