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

📄 extend.texi

📁 早期freebsd实现
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
@cindex underscores in variables in macros@cindex @samp{_} in variables in macros@cindex local variables in macros@cindex variables, local, in macros@cindex macros, local variables inThe reason for using names that start with underscores for the localvariables is to avoid conflicts with variable names that occur within theexpressions that are substituted for @code{a} and @code{b}.  Eventually wehope to design a new form of declaration syntax that allows you to declarevariables whose scopes start only after their initializers; this will be amore reliable way to prevent such conflicts.@node Typeof@section Referring to a Type with @code{typeof}@findex typeof@findex sizeof@cindex macros, types of argumentsAnother way to refer to the type of an expression is with @code{typeof}.The syntax of using of this keyword looks like @code{sizeof}, but theconstruct acts semantically like a type name defined with @code{typedef}.There are two ways of writing the argument to @code{typeof}: with anexpression or with a type.  Here is an example with an expression:@exampletypeof (x[0](1))@end example@noindentThis assumes that @code{x} is an array of functions; the type describedis that of the values of the functions.Here is an example with a typename as the argument:@exampletypeof (int *)@end example@noindentHere the type described is that of pointers to @code{int}.If you are writing a header file that must work when included in ANSI Cprograms, write @code{__typeof__} instead of @code{typeof}.@xref{Alternate Keywords}.A @code{typeof}-construct can be used anywhere a typedef name could beused.  For example, you can use it in a declaration, in a cast, or insideof @code{sizeof} or @code{typeof}.@itemize @bullet@itemThis declares @code{y} with the type of what @code{x} points to.@exampletypeof (*x) y;@end example@itemThis declares @code{y} as an array of such values.@exampletypeof (*x) y[4];@end example@itemThis declares @code{y} as an array of pointers to characters:@exampletypeof (typeof (char *)[4]) y;@end example@noindentIt is equivalent to the following traditional C declaration:@examplechar *y[4];@end exampleTo see the meaning of the declaration using @code{typeof}, and why itmight be a useful way to write, let's rewrite it with these macros:@example#define pointer(T)  typeof(T *)#define array(T, N) typeof(T [N])@end example@noindentNow the declaration can be rewritten this way:@examplearray (pointer (char), 4) y;@end example@noindentThus, @code{array (pointer (char), 4)} is the type of arrays of 4pointers to @code{char}.@end itemize@node Lvalues@section Generalized Lvalues@cindex compound expressions as lvalues@cindex expressions, compound, as lvalues@cindex conditional expressions as lvalues@cindex expressions, conditional, as lvalues@cindex casts as lvalues@cindex generalized lvalues@cindex lvalues, generalized@cindex extensions, @code{?:}@cindex @code{?:} extensionsCompound expressions, conditional expressions and casts are allowed aslvalues provided their operands are lvalues.  This means that you can taketheir addresses or store values into them.For example, a compound expression can be assigned, provided the lastexpression in the sequence is an lvalue.  These two expressions areequivalent:@example(a, b) += 5a, (b += 5)@end exampleSimilarly, the address of the compound expression can be taken.  These twoexpressions are equivalent:@example&(a, b)a, &b@end exampleA conditional expression is a valid lvalue if its type is not void and thetrue and false branches are both valid lvalues.  For example, these twoexpressions are equivalent:@example(a ? b : c) = 5(a ? b = 5 : (c = 5))@end exampleA cast is a valid lvalue if its operand is an lvalue.  A simpleassignment whose left-hand side is a cast works by converting theright-hand side first to the specified type, then to the type of theinner left-hand side expression.  After this is stored, the value isconverted back to the specified type to become the value of theassignment.  Thus, if @code{a} has type @code{char *}, the following twoexpressions are equivalent:@example(int)a = 5(int)(a = (char *)(int)5)@end exampleAn assignment-with-arithmetic operation such as @samp{+=} applied to a castperforms the arithmetic using the type resulting from the cast, and thencontinues as in the previous case.  Therefore, these two expressions areequivalent:@example(int)a += 5(int)(a = (char *)(int) ((int)a + 5))@end exampleYou cannot take the address of an lvalue cast, because the use of itsaddress would not work out coherently.  Suppose that @code{&(int)f} werepermitted, where @code{f} has type @code{float}.  Then the followingstatement would try to store an integer bit-pattern where a floatingpoint number belongs:@example*&(int)f = 1;@end exampleThis is quite different from what @code{(int)f = 1} would do---thatwould convert 1 to floating point and store it.  Rather than cause thisinconsistency, we think it is better to prohibit use of @samp{&} on a cast.If you really do want an @code{int *} pointer with the address of@code{f}, you can simply write @code{(int *)&f}.@node Conditionals@section Conditional Expressions with Omitted Operands@cindex conditional expressions, extensions@cindex omitted middle-operands@cindex middle-operands, omitted@cindex extensions, @code{?:}@cindex @code{?:} extensionsThe middle operand in a conditional expression may be omitted.  Thenif the first operand is nonzero, its value is the value of the conditionalexpression.Therefore, the expression@examplex ? : y@end example@noindenthas the value of @code{x} if that is nonzero; otherwise, the value of@code{y}.This example is perfectly equivalent to@examplex ? x : y@end example@cindex side effect in ?:@cindex ?: side effect@noindentIn this simple case, the ability to omit the middle operand is notespecially useful.  When it becomes useful is when the first operand does,or may (if it is a macro argument), contain a side effect.  Then repeatingthe operand in the middle would perform the side effect twice.  Omittingthe middle operand uses the value already computed without the undesirableeffects of recomputing it.@node Long Long@section Double-Word Integers@cindex @code{long long} data types@cindex double-word arithmetic@cindex multiprecision arithmeticGNU C supports data types for integers that are twice as long as@code{long int}.  Simply write @code{long long int} for a signedinteger, or @code{unsigned long long int} for an unsigned integer.You can use these types in arithmetic like any other integer types.Addition, subtraction, and bitwise boolean operations on these typesare open-coded on all types of machines.  Multiplication is open-codedif the machine supports fullword-to-doubleword a widening multiplyinstruction.  Division and shifts are open-coded only on machines thatprovide special support.  The operations that are not open-coded usespecial library routines that come with GNU CC.There may be pitfalls when you use @code{long long} types for functionarguments, unless you declare function prototypes.  If a functionexpects type @code{int} for its argument, and you pass a value of type@code{long long int}, confusion will result because the caller and thesubroutine will disagree about the number of bytes for the argument.Likewise, if the function expects @code{long long int} and you pass@code{int}.  The best way to avoid such problems is to use prototypes.@node Zero Length@section Arrays of Length Zero@cindex arrays of length zero@cindex zero-length arrays@cindex length-zero arraysZero-length arrays are allowed in GNU C.  They are very useful as the lastelement of a structure which is really a header for a variable-lengthobject:@examplestruct line @{  int length;  char contents[0];@};@{  struct line *thisline = (struct line *)    malloc (sizeof (struct line) + this_length);  thisline->length = this_length;@}@end exampleIn standard C, you would have to give @code{contents} a length of 1, whichmeans either you waste space or complicate the argument to @code{malloc}.@node Variable Length@section Arrays of Variable Length@cindex variable-length arrays@cindex arrays of variable lengthVariable-length automatic arrays are allowed in GNU C.  These arrays aredeclared like any other automatic arrays, but with a length that is nota constant expression.  The storage is allocated at the point ofdeclaration and deallocated when the brace-level is exited.  Forexample:@exampleFILE *concat_fopen (char *s1, char *s2, char *mode)@{  char str[strlen (s1) + strlen (s2) + 1];  strcpy (str, s1);  strcat (str, s2);  return fopen (str, mode);@}@end example@cindex scope of a variable length array@cindex variable-length array scope@cindex deallocating variable length arraysJumping or breaking out of the scope of the array name deallocates thestorage.  Jumping into the scope is not allowed; you get an errormessage for it.@cindex @code{alloca} vs variable-length arraysYou can use the function @code{alloca} to get an effect much likevariable-length arrays.  The function @code{alloca} is available inmany other C implementations (but not in all).  On the other hand,variable-length arrays are more elegant.There are other differences between these two methods.  Space allocatedwith @code{alloca} exists until the containing @emph{function} returns.The space for a variable-length array is deallocated as soon as the arrayname's scope ends.  (If you use both variable-length arrays and@code{alloca} in the same function, deallocation of a variable-length arraywill also deallocate anything more recently allocated with @code{alloca}.)You can also use variable-length arrays as arguments to functions:@examplestruct entrytester (int len, char data[len][len])@{  @dots{}@}@end exampleThe length of an array is computed once when the storage is allocatedand is remembered for the scope of the array in case you access it with@code{sizeof}.If you want to pass the array first and the length afterward, you canuse a forward declaration in the parameter list---another GNU extension.@examplestruct entrytester (int len; char data[len][len], int len)@{  @dots{}@}@end example@cindex parameter forward declarationThe @samp{int len} before the semicolon is a @dfn{parameter forwarddeclaration}, and it serves the purpose of making the name @code{len}known when the declaration of @code{data} is parsed.You can write any number of such parameter forward declarations in theparameter list.  They can be separated by commas or semicolons, but thelast one must end with a semicolon, which is followed by the ``real''parameter declarations.  Each forward declaration must match a ``real''declaration in parameter name and data type.@node Macro Varargs@section Macros with Variable Numbers of Arguments@cindex variable number of arguments@cindex macro with variable arguments@cindex rest argument (in macro)In GNU C, a macro can accept a variable number of arguments, much as afunction can.  The syntax for defining the macro looks much like thatused for a function.  Here is an example:@example#define eprintf(format, args...)  \ fprintf (stderr, format, ## args)@end exampleHere @code{args} is a @dfn{rest argument}: it takes in zero or morearguments, as many as the call contains.  All of them plus the commasbetween them form the value of @code{args}, which is substituted intothe macro body where @code{args} is used.  Thus, we have theseexpansions:

⌨️ 快捷键说明

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