diff options
| author | Andrew Lee <alee14498@protonmail.com> | 2021-08-15 00:34:05 -0400 |
|---|---|---|
| committer | Andrew Lee <alee14498@protonmail.com> | 2021-08-15 00:34:05 -0400 |
| commit | 60cc83bf91bfc9bb02f6304b5d6c8234ba6d210f (patch) | |
| tree | fdc0be85a1ca35e34c3ae2c805fe9b718e3c1091 /gcc-1.40/gcc.info-4 | |
| parent | dd8dfab51b832a654365ed00c06bf802ff628bfa (diff) | |
| download | linux-0.01-distro-master.tar.gz linux-0.01-distro-master.tar.bz2 linux-0.01-distro-master.zip | |
Diffstat (limited to 'gcc-1.40/gcc.info-4')
| -rw-r--r-- | gcc-1.40/gcc.info-4 | 1022 |
1 files changed, 1022 insertions, 0 deletions
diff --git a/gcc-1.40/gcc.info-4 b/gcc-1.40/gcc.info-4 new file mode 100644 index 0000000..0e44e41 --- /dev/null +++ b/gcc-1.40/gcc.info-4 @@ -0,0 +1,1022 @@ +Info file gcc.info, produced by Makeinfo, -*- Text -*- from input +file gcc.texinfo. + + This file documents the use and the internals of the GNU compiler. + + Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided also +that the sections entitled "GNU General Public License" and "Protect +Your Freedom--Fight `Look And Feel'" are included exactly as in the +original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this +one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that the sections entitled "GNU General Public +License" and "Protect Your Freedom--Fight `Look And Feel'" and this +permission notice may be included in translations approved by the +Free Software Foundation instead of in the original English. + + +File: gcc.info, Node: Naming Types, Next: Typeof, Prev: Statement Exprs, Up: Extensions + +Naming an Expression's Type +=========================== + + You can give a name to the type of an expression using a `typedef' +declaration with an initializer. Here is how to define NAME as a +type name for the type of EXP: + + typedef NAME = EXP; + + This is useful in conjunction with the +statements-within-expressions feature. Here is how the two together +can be used to define a safe "maximum" macro that operates on any +arithmetic type: + + #define max(a,b) \ + ({typedef _ta = (a), _tb = (b); \ + _ta _a = (a); _tb _b = (b); \ + _a > _b ? _a : _b; }) + + The reason for using names that start with underscores for the +local variables is to avoid conflicts with variable names that occur +within the expressions that are substituted for `a' and `b'. +Eventually we hope to design a new form of declaration syntax that +allows you to declare variables whose scopes start only after their +initializers; this will be a more reliable way to prevent such +conflicts. + + +File: gcc.info, Node: Typeof, Next: Lvalues, Prev: Naming Types, Up: Extensions + +Referring to a Type with `typeof' +================================= + + Another way to refer to the type of an expression is with `typeof'. +The syntax of using of this keyword looks like `sizeof', but the +construct acts semantically like a type name defined with `typedef'. + + There are two ways of writing the argument to `typeof': with an +expression or with a type. Here is an example with an expression: + + typeof (x[0](1)) + +This assumes that `x' is an array of functions; the type described is +that of the values of the functions. + + Here is an example with a typename as the argument: + + typeof (int *) + +Here the type described is that of pointers to `int'. + + If you are writing a header file that must work when included in +ANSI C programs, write `__typeof__' instead of `typeof'. *Note +Alternate Keywords::. + + A `typeof'-construct can be used anywhere a typedef name could be +used. For example, you can use it in a declaration, in a cast, or +inside of `sizeof' or `typeof'. + + * This declares `y' with the type of what `x' points to. + + typeof (*x) y; + + * This declares `y' as an array of such values. + + typeof (*x) y[4]; + + * This declares `y' as an array of pointers to characters: + + typeof (typeof (char *)[4]) y; + + It is equivalent to the following traditional C declaration: + + char *y[4]; + + To see the meaning of the declaration using `typeof', and why it + might be a useful way to write, let's rewrite it with these + macros: + + #define pointer(T) typeof(T *) + #define array(T, N) typeof(T [N]) + + Now the declaration can be rewritten this way: + + array (pointer (char), 4) y; + + Thus, `array (pointer (char), 4)' is the type of arrays of 4 + pointers to `char'. + + +File: gcc.info, Node: Lvalues, Next: Conditionals, Prev: Typeof, Up: Extensions + +Generalized Lvalues +=================== + + Compound expressions, conditional expressions and casts are +allowed as lvalues provided their operands are lvalues. This means +that you can take their addresses or store values into them. + + For example, a compound expression can be assigned, provided the +last expression in the sequence is an lvalue. These two expressions +are equivalent: + + (a, b) += 5 + a, (b += 5) + + Similarly, the address of the compound expression can be taken. +These two expressions are equivalent: + + &(a, b) + a, &b + + A conditional expression is a valid lvalue if its type is not void +and the true and false branches are both valid lvalues. For example, +these two expressions are equivalent: + + (a ? b : c) = 5 + (a ? b = 5 : (c = 5)) + + A cast is a valid lvalue if its operand is valid. Taking the +address of the cast is the same as taking the address without a cast, +except for the type of the result. For example, these two +expressions are equivalent (but the second may be valid when the type +of `a' does not permit a cast to `int *'). + + &(int *)a + (int **)&a + + A simple assignment whose left-hand side is a cast works by +converting the right-hand side first to the specified type, then to +the type of the inner left-hand side expression. After this is +stored, the value is converter back to the specified type to become +the value of the assignment. Thus, if `a' has type `char *', the +following two expressions are equivalent: + + (int)a = 5 + (int)(a = (char *)5) + + An assignment-with-arithmetic operation such as `+=' applied to a +cast performs the arithmetic using the type resulting from the cast, +and then continues as in the previous case. Therefore, these two +expressions are equivalent: + + (int)a += 5 + (int)(a = (char *) ((int)a + 5)) + + +File: gcc.info, Node: Conditionals, Next: Zero-Length, Prev: Lvalues, Up: Extensions + +Conditional Expressions with Omitted Middle-Operands +==================================================== + + The middle operand in a conditional expression may be omitted. +Then if the first operand is nonzero, its value is the value of the +conditional expression. + + Therefore, the expression + + x ? : y + +has the value of `x' if that is nonzero; otherwise, the value of `y'. + + This example is perfectly equivalent to + + x ? x : y + +In this simple case, the ability to omit the middle operand is not +especially useful. When it becomes useful is when the first operand +does, or may (if it is a macro argument), contain a side effect. +Then repeating the operand in the middle would perform the side +effect twice. Omitting the middle operand uses the value already +computed without the undesirable effects of recomputing it. + + +File: gcc.info, Node: Zero-Length, Next: Variable-Length, Prev: Conditionals, Up: Extensions + +Arrays of Length Zero +===================== + + Zero-length arrays are allowed in GNU C. They are very useful as +the last element of a structure which is really a header for a +variable-length object: + + struct line { + int length; + char contents[0]; + }; + + { + struct line *thisline + = (struct line *) malloc (sizeof (struct line) + this_length); + thisline->length = this_length; + } + + In standard C, you would have to give `contents' a length of 1, +which means either you waste space or complicate the argument to +`malloc'. + + +File: gcc.info, Node: Variable-Length, Next: Subscripting, Prev: Zero-Length, Up: Extensions + +Arrays of Variable Length +========================= + + Variable-length automatic arrays are allowed in GNU C. These +arrays are declared like any other automatic arrays, but with a +length that is not a constant expression. The storage is allocated +at that time and deallocated when the brace-level is exited. For +example: + + FILE *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); + } + + You can also use variable-length arrays as arguments to functions: + + struct entry + tester (int len, char data[len]) + { + ... + } + + The length of an array is computed on entry to the brace-level +where the array is declared and is remembered for the scope of the +array in case you access it with `sizeof'. + + Jumping or breaking out of the scope of the array name will also +deallocate the storage. Jumping into the scope is not allowed; you +will get an error message for it. + + You can use the function `alloca' to get an effect much like +variable-length arrays. The function `alloca' is available in many +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 +allocated with `alloca' exists until the containing *function* returns. +The space for a variable-length array is deallocated as soon as the +array name's scope ends. (If you use both variable-length arrays and +`alloca' in the same function, deallocation of a variable-length +array will also deallocate anything more recently allocated with +`alloca'.) + + +File: gcc.info, Node: Subscripting, Next: Pointer Arith, Prev: Variable-Length, Up: Extensions + +Non-Lvalue Arrays May Have Subscripts +===================================== + + Subscripting is allowed on arrays that are not lvalues, even +though the unary `&' operator is not. For example, this is valid in +GNU C though not valid in other C dialects: + + struct foo {int a[4];}; + + struct foo f(); + + bar (int index) + { + return f().a[index]; + } + + +File: gcc.info, Node: Pointer Arith, Next: Initializers, Prev: Subscripting, Up: Extensions + +Arithmetic on `void'-Pointers and Function Pointers +=================================================== + + In GNU C, addition and subtraction operations are supported on +pointers to `void' and on pointers to functions. This is done by +treating the size of a `void' or of a function as 1. + + A consequence of this is that `sizeof' is also allowed on `void' +and on function types, and returns 1. + + The option `-Wpointer-arith' requests a warning if these +extensions are used. + + +File: gcc.info, Node: Initializers, Next: Constructors, Prev: Pointer Arith, Up: Extensions + +Non-Constant Initializers +========================= + + The elements of an aggregate initializer for an automatic variable +are not required to be constant expressions in GNU C. Here is an +example of an initializer with run-time varying elements: + + foo (float f, float g) + { + float beat_freqs[2] = { f-g, f+g }; + ... + } + + +File: gcc.info, Node: Constructors, Next: Function Attributes, Prev: Initializers, Up: Extensions + +Constructor Expressions +======================= + + GNU C supports constructor expressions. A constructor looks like +a cast containing an initializer. Its value is an object of the type +specified in the cast, containing the elements specified in the +initializer. The type must be a structure, union or array type. + + Assume that `struct foo' and `structure' are declared as shown: + + struct foo {int a; char b[2];} structure; + +Here is an example of constructing a `struct foo' with a constructor: + + structure = ((struct foo) {x + y, 'a', 0}); + +This is equivalent to writing the following: + + { + struct foo temp = {x + y, 'a', 0}; + structure = temp; + } + + You can also construct an array. If all the elements of the +constructor are (made up of) simple constant expressions, suitable +for use in initializers, then the constructor is an lvalue and can be +coerced to a pointer to its first element, as shown here: + + char **foo = (char *[]) { "x", "y", "z" }; + + Array constructors whose elements are not simple constants are not +very useful, because the constructor is not an lvalue. There are +only two valid ways to use it: to subscript it, or initialize an +array variable with it. The former is probably slower than a +`switch' statement, while the latter does the same thing an ordinary +C initializer would do. + + output = ((int[]) { 2, x, 28 }) [input]; + + +File: gcc.info, Node: Function Attributes, Next: Dollar Signs, Prev: Constructors, Up: Extensions + +Declaring Attributes of Functions +================================= + + In GNU C, you declare certain things about functions called in +your program which help the compiler optimize function calls. + + A few functions, such as `abort' and `exit', cannot return. These +functions should be declared `volatile'. For example, + + extern volatile void abort (); + +tells the compiler that it can assume that `abort' will not return. +This makes slightly better code, but more importantly it helps avoid +spurious warnings of uninitialized variables. + + Many functions do not examine any values except their arguments, +and have no effects except the return value. Such a function can be +subject to common subexpression elimination and loop optimization +just as an arithmetic operator would be. These functions should be +declared `const'. For example, + + extern const void square (); + +says that the hypothetical function `square' is safe to call fewer +times than the program says. + + Note that a function that has pointer arguments and examines the +data pointed to must *not* be declared `const'. Likewise, a function +that calls a non-`const' function usually must not be `const'. + + Some people object to this feature, claiming that ANSI C's +`#pragma' should be used instead. There are two reasons I did not do +this. + + 1. It is impossible to generate `#pragma' commands from a macro. + + 2. The `#pragma' command is just as likely as these keywords to + mean something else in another compiler. + + These two reasons apply to *any* application whatever: as far as I +can see, `#pragma' is never useful. + + +File: gcc.info, Node: Dollar Signs, Next: Alignment, Prev: Function Attributes, Up: Extensions + +Dollar Signs in Identifier Names +================================ + + In GNU C, you may use dollar signs in identifier names. This is +because many traditional C implementations allow such identifiers. + + Dollar signs are allowed if you specify `-traditional'; they are +not allowed if you specify `-ansi'. Whether they are allowed by +default depends on the target machine; usually, they are not. + + +File: gcc.info, Node: Alignment, Next: Inline, Prev: Dollar Signs, Up: Extensions + +Inquiring about the Alignment of a Type or Variable +=================================================== + + The keyword `__alignof__' allows you to inquire about how an +object is aligned, or the minimum alignment usually required by a +type. Its syntax is just like `sizeof'. + + For example, if the target machine requires a `double' value to be +aligned on an 8-byte boundary, then `__alignof__ (double)' is 8. +This is true on many RISC machines. On more traditional machine +designs, `__alignof__ (double)' is 4 or even 2. + + Some machines never actually require alignment; they allow +reference to any data type even at an odd addresses. For these +machines, `__alignof__' reports the *recommended* alignment of a type. + + When the operand of `__alignof__' is an lvalue rather than a type, +the value is the largest alignment that the lvalue is known to have. +It may have this alignment as a result of its data type, or because +it is part of a structure and inherits alignment from that structure. +For example, after this declaration: + + struct foo { int x; char y; } foo1; + +the value of `__alignof__ (foo1.y)' is probably 2 or 4, the same as +`__alignof__ (int)', even though the data type of `foo1.y' does not +itself demand any alignment. + + +File: gcc.info, Node: Inline, Next: Extended Asm, Prev: Alignment, Up: Extensions + +An Inline Function is As Fast As a Macro +======================================== + + By declaring a function `inline', you can direct GNU CC to +integrate that function's code into the code for its callers. This +makes execution faster by eliminating the function-call overhead; in +addition, if any of the actual argument values are constant, their +known values may permit simplifications at compile time so that not +all of the inline function's code needs to be included. + + To declare a function inline, use the `inline' keyword in its +declaration, like this: + + inline int + inc (int *a) + { + (*a)++; + } + + (If you are writing a header file to be included in ANSI C +programs, write `__inline__' instead of `inline'. *Note Alternate +Keywords::.) + + You can also make all "simple enough" functions inline with the +option `-finline-functions'. Note that certain usages in a function +definition can make it unsuitable for inline substitution. + + When a function is both inline and `static', if all calls to the +function are integrated into the caller, and the function's address +is never used, then the function's own assembler code is never +referenced. In this case, GNU CC does not actually output assembler +code for the function, unless you specify the option +`-fkeep-inline-functions'. Some calls cannot be integrated for +various reasons (in particular, calls that precede the function's +definition cannot be integrated, and neither can recursive calls +within the definition). If there is a nonintegrated call, then the +function is compiled to assembler code as usual. The function must +also be compiled as usual if the program refers to its address, +because that can't be inlined. + + When an inline function is not `static', then the compiler must +assume that there may be calls from other source files; since a +global symbol can be defined only once in any program, the function +must not be defined in the other source files, so the calls therein +cannot be integrated. Therefore, a non-`static' inline function is +always compiled on its own in the usual fashion. + + If you specify both `inline' and `extern' in the function +definition, then the definition is used only for inlining. In no +case is the function compiled on its own, not even if you refer to +its address explicitly. Such an address becomes an external +reference, as if you had only declared the function, and had not +defined it. + + This combination of `inline' and `extern' has almost the effect of +a macro. The way to use it is to put a function definition in a +header file with these keywords, and put another copy of the +definition (lacking `inline' and `extern') in a library file. The +definition in the header file will cause most calls to the function +to be inlined. If any uses of the function remain, they will refer +to the single copy in the library. + + +File: gcc.info, Node: Extended Asm, Next: Asm Labels, Prev: Inline, Up: Extensions + +Assembler Instructions with C Expression Operands +================================================= + + In an assembler instruction using `asm', you can now specify the +operands of the instruction using C expressions. This means no more +guessing which registers or memory locations will contain the data +you want to use. + + You must specify an assembler instruction template much like what +appears in a machine description, plus an operand constraint string +for each operand. + + For example, here is how to use the 68881's `fsinx' instruction: + + asm ("fsinx %1,%0" : "=f" (result) : "f" (angle)); + +Here `angle' is the C expression for the input operand while `result' +is that of the output operand. Each has `"f"' as its operand +constraint, saying that a floating-point register is required. The +`=' in `=f' indicates that the operand is an output; all output +operands' constraints must use `='. The constraints use the same +language used in the machine description (*note Constraints::.). + + Each operand is described by an operand-constraint string followed +by the C expression in parentheses. A colon separates the assembler +template from the first output operand, and another separates the +last output operand from the first input, if any. Commas separate +output operands and separate inputs. The total number of operands is +limited to the maximum number of operands in any instruction pattern +in the machine description. + + If there are no output operands, and there are input operands, +then there must be two consecutive colons surrounding the place where +the output operands would go. + + Output operand expressions must be lvalues; the compiler can check +this. The input operands need not be lvalues. The compiler cannot +check whether the operands have data types that are reasonable for +the instruction being executed. It does not parse the assembler +instruction template and does not know what it means, or whether it +is valid assembler input. The extended `asm' feature is most often +used for machine instructions that the compiler itself does not know +exist. + + The output operands must be write-only; GNU CC will assume that +the values in these operands before the instruction are dead and need +not be generated. Extended asm does not support input-output or +read-write operands. For this reason, the constraint character `+', +which indicates such an operand, may not be used. + + When the assembler instruction has a read-write operand, or an +operand in which only some of the bits are to be changed, you must +logically split its function into two separate operands, one input +operand and one write-only output operand. The connection between +them is expressed by constraints which say they need to be in the +same location when the instruction executes. You can use the same C +expression for both operands, or different expressions. For example, +here we write the (fictitious) `combine' instruction with `bar' as +its read-only source operand and `foo' as its read-write destination: + + asm ("combine %2,%0" : "=r" (foo) : "0" (foo), "g" (bar)); + +The constraint `"0"' for operand 1 says that it must occupy the same +location as operand 0. A digit in constraint is allowed only in an +input operand, and it must refer to an output operand. + + Only a digit in the constraint can guarantee that one operand will +be in the same place as another. The mere fact that `foo' is the +value of both operands is not enough to guarantee that they will be +in the same place in the generated assembler code. The following +would not work: + + asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar)); + + Various optimizations or reloading could cause operands 0 and 1 to +be in different registers; GNU CC knows no reason not to do so. For +example, the compiler might find a copy of the value of `foo' in one +register and use it for operand 1, but generate the output operand 0 +in a different register (copying it afterward to `foo''s own +address). Of course, since the register for operand 1 is not even +mentioned in the assembler code, the result will not work, but GNU CC +can't tell that. + + Unless an output operand has the `&' constraint modifier, GNU CC +may allocate it in the same register as an unrelated input operand, +on the assumption that the inputs are consumed before the outputs are +produced. This assumption may be false if the assembler code +actually consists of more than one instruction. In such a case, use +`&' for each output operand that may not overlap an input. *Note +Modifiers::. + + Some instructions clobber specific hard registers. To describe +this, write a third colon after the input operands, followed by the +names of the clobbered hard registers (given as strings). Here is a +realistic example for the vax: + + asm volatile ("movc3 %0,%1,%2" + : /* no outputs */ + : "g" (from), "g" (to), "g" (count) + : "r0", "r1", "r2", "r3", "r4", "r5"); + + You can put multiple assembler instructions together in a single +`asm' template, separated either with newlines (written as `\n') or +with semicolons if the assembler allows such semicolons. The GNU +assembler allows semicolons and all Unix assemblers seem to do so. +The input operands are guaranteed not to use any of the clobbered +registers, and neither will the output operands' addresses, so you +can read and write the clobbered registers as many times as you like. +Here is an example of multiple instructions in a template; it assumes +that the subroutine `_foo' accepts arguments in registers 9 and 10: + + asm ("movl %0,r9;movl %1,r10;call _foo" + : /* no outputs */ + : "g" (from), "g" (to) + : "r9", "r10"); + + If you want to test the condition code produced by an assembler +instruction, you must include a branch and a label in the `asm' +construct, as follows: + + asm ("clr %0;frob %1;beq 0f;mov #1,%0;0:" + : "g" (result) + : "g" (input)); + +This assumes your assembler supports local labels, as the GNU +assembler and most Unix assemblers do. + + Usually the most convenient way to use these `asm' instructions is +to encapsulate them in macros that look like functions. For example, + + #define sin(x) \ + ({ double __value, __arg = (x); \ + asm ("fsinx %1,%0": "=f" (__value): "f" (__arg)); \ + __value; }) + +Here the variable `__arg' is used to make sure that the instruction +operates on a proper `double' value, and to accept only those +arguments `x' which can convert automatically to a `double'. + + Another way to make sure the instruction operates on the correct +data type is to use a cast in the `asm'. This is different from +using a variable `__arg' in that it converts more different types. +For example, if the desired type were `int', casting the argument to +`int' would accept a pointer with no complaint, while assigning the +argument to an `int' variable named `__arg' would warn about using a +pointer unless the caller explicitly casts it. + + If an `asm' has output operands, GNU CC assumes for optimization +purposes that the instruction has no side effects except to change +the output operands. This does not mean that instructions with a +side effect cannot be used, but you must be careful, because the +compiler may eliminate them if the output operands aren't used, or +move them out of loops, or replace two with one if they constitute a +common subexpression. Also, if your instruction does have a side +effect on a variable that otherwise appears not to change, the old +value of the variable may be reused later if it happens to be found +in a register. + + You can prevent an `asm' instruction from being deleted, moved or +combined by writing the keyword `volatile' after the `asm'. For +example: + + #define set_priority(x) \ + asm volatile ("set_priority %0": /* no outputs */ : "g" (x)) + +(However, an instruction without output operands will not be deleted +or moved, regardless, unless it is unreachable.) + + It is a natural idea to look for a way to give access to the +condition code left by the assembler instruction. However, when we +attempted to implement this, we found no way to make it work +reliably. The problem is that output operands might need reloading, +which would result in additional following "store" instructions. On +most machines, these instructions would alter the condition code +before there was time to test it. This problem doesn't arise for +ordinary "test" and "compare" instructions because they don't have +any output operands. + + If you are writing a header file that should be includable in ANSI +C programs, write `__asm__' instead of `asm'. *Note Alternate +Keywords::. + + +File: gcc.info, Node: Asm Labels, Next: Explicit Reg Vars, Prev: Extended Asm, Up: Extensions + +Controlling Names Used in Assembler Code +======================================== + + You can specify the name to be used in the assembler code for a C +function or variable by writing the `asm' (or `__asm__') keyword +after the declarator as follows: + + int foo asm ("myfoo") = 2; + +This specifies that the name to be used for the variable `foo' in the +assembler code should be `myfoo' rather than the usual `_foo'. + + On systems where an underscore is normally prepended to the name +of a C function or variable, this feature allows you to define names +for the linker that do not start with an underscore. + + You cannot use `asm' in this way in a function *definition*; but +you can get the same effect by writing a declaration for the function +before its definition and putting `asm' there, like this: + + extern func () asm ("FUNC"); + + func (x, y) + int x, y; + ... + + It is up to you to make sure that the assembler names you choose +do not conflict with any other assembler symbols. Also, you must not +use a register name; that would produce completely invalid assembler +code. GNU CC does not as yet have the ability to store static +variables in registers. Perhaps that will be added. + + +File: gcc.info, Node: Explicit Reg Vars, Next: Alternate Keywords, Prev: Asm Labels, Up: Extensions + +Variables in Specified Registers +================================ + + GNU C allows you to put a few global variables into specified +hardware registers. You can also specify the register in which an +ordinary register variable should be allocated. + + * Global register variables reserve registers throughout the + program. This may be useful in programs such as programming + language interpreters which have a couple of global variables + that are accessed very often. + + * Local register variables in specific registers do not reserve + the registers. The compiler's data flow analysis is capable of + determining where the specified registers contain live values, + and where they are available for other uses. These local + variables are sometimes convenient for use with the extended + `asm' feature (*note Extended Asm::.). + +* Menu: + +* Global Reg Vars:: +* Local Reg Vars:: + + +File: gcc.info, Node: Global Reg Vars, Next: Local Reg Vars, Prev: Explicit Reg Vars, Up: Explicit Reg Vars + +Defining Global Register Variables +---------------------------------- + + You can define a global register variable in GNU C like this: + + register int *foo asm ("a5"); + +Here `a5' is the name of the register which should be used. Choose a +register which is normally saved and restored by function calls on +your machine, so that library routines will not clobber it. + + Naturally the register name is cpu-dependent, so you would need to +conditionalize your program according to cpu type. The register `a5' +would be a good choice on a 68000 for a variable of pointer type. On +machines with register windows, be sure to choose a "global" register +that is not affected magically by the function call mechanism. + + In addition, operating systems on one type of cpu may differ in +how they name the registers; then you would need additional +conditionals. For example, some 68000 operating systems call this +register `%a5'. + + Eventually there may be a way of asking the compiler to choose a +register automatically, but first we need to figure out how it should +choose and how to enable you to guide the choice. No solution is +evident. + + Defining a global register variable in a certain register reserves +that register entirely for this use, at least within the current +compilation. The register will not be allocated for any other +purpose in the functions in the current compilation. The register +will not be saved and restored by these functions. Stores into this +register are never deleted even if they would appear to be dead, but +references may be deleted or moved or simplified. + + It is not safe to access the global register variables from signal +handlers, or from more than one thread of control, because the system +library routines may temporarily use the register for other things +(unless you recompile them specially for the task at hand). + + It is not safe for one function that uses a global register +variable to call another such function `foo' by way of a third +function `lose' that was compiled without knowledge of this variable +(i.e. in a different source file in which the variable wasn't +declared). This is because `lose' might save the register and put +some other value there. For example, you can't expect a global +register variable to be available in the comparison-function that you +pass to `qsort', since `qsort' might have put something else in that +register. (If you are prepared to recompile `qsort' with the same +global register variable, you can solve this problem.) + + If you want to recompile `qsort' or other source files which do +not actually use your global register variable, so that they will not +use that register for any other purpose, then it suffices to specify +the compiler option `-ffixed-REG'. You need not actually add a +global register declaration to their source code. + + A function which can alter the value of a global register variable +cannot safely be called from a function compiled without this +variable, because it could clobber the value the caller expects to +find there on return. Therefore, the function which is the entry +point into the part of the program that uses the global register +variable must explicitly save and restore the value which belongs to +its caller. + + On most machines, `longjmp' will restore to each global register +variable the value it had at the time of the `setjmp'. On some +machines, however, `longjmp' will not change the value of global +register variables. To be portable, the function that called +`setjmp' should make other arrangements to save the values of the +global register variables, and to restore them in a `longjmp'. This +way, the same thing will happen regardless of what `longjmp' does. + + All global register variable declarations must precede all +function definitions. If such a declaration could appear after +function definitions, the declaration would be too late to prevent +the register from being used for other purposes in the preceding +functions. + + Global register variables may not have initial values, because an +executable file has no means to supply initial contents for a register. + + +File: gcc.info, Node: Local Reg Vars, Prev: Global Reg Vars, Up: Explicit Reg Vars + +Specifying Registers for Local Variables +---------------------------------------- + + You can define a local register variable with a specified register +like this: + + register int *foo asm ("a5"); + +Here `a5' is the name of the register which should be used. Note +that this is the same syntax used for defining global register +variables, but for a local variable it would appear within a function. + + Naturally the register name is cpu-dependent, but this is not a +problem, since specific registers are most often useful with explicit +assembler instructions (*note Extended Asm::.). Both of these things +generally require that you conditionalize your program according to +cpu type. + + In addition, operating systems on one type of cpu may differ in +how they name the registers; then you would need additional +conditionals. For example, some 68000 operating systems call this +register `%a5'. + + Eventually there may be a way of asking the compiler to choose a +register automatically, but first we need to figure out how it should +choose and how to enable you to guide the choice. No solution is +evident. + + Defining such a register variable does not reserve the register; +it remains available for other uses in places where flow control +determines the variable's value is not live. However, these +registers are made unavailable for use in the reload pass. I would +not be surprised if excessive use of this feature leaves the compiler +too few available registers to compile certain functions. + + +File: gcc.info, Node: Alternate Keywords, Prev: Explicit Reg Vars, Up: Extensions + +Alternate Keywords +================== + + The option `-traditional' disables certain keywords; `-ansi' +disables certain others. This causes trouble when you want to use +GNU C extensions, or ANSI C features, in a general-purpose header +file that should be usable by all programs, including ANSI C programs +and traditional ones. The keywords `asm', `typeof' and `inline' +cannot be used since they won't work in a program compiled with +`-ansi', while the keywords `const', `volatile', `signed', `typeof' +and `inline' won't work in a program compiled with `-traditional'. + + The way to solve these problems is to put `__' at the beginning +and end of each problematical keyword. For example, use `__asm__' +instead of `asm', `__const__' instead of `const', and `__inline__' +instead of `inline'. + + Other C compilers won't accept these alternative keywords; if you +want to compile with another compiler, you can define the alternate +keywords as macros to replace them with the customary keywords. It +looks like this: + + #ifndef __GNUC__ + #define __asm__ asm + #endif + + +File: gcc.info, Node: Bugs, Next: Portability, Prev: Extensions, Up: Top + +Reporting Bugs +************** + + Your bug reports play an essential role in making GNU CC reliable. + + When you encounter a problem, the first thing to do is to see if +it is already known. *Note Trouble::. Also look in *Note +Incompatibilities::. If it isn't known, then you should report the +problem. + + Reporting a bug may help you by bringing a solution to your +problem, or it may not. (If it does not, look in the service +directory; see *Note Service::.) In any case, the principal function +of a bug report is to help the entire community by making the next +version of GNU CC work better. Bug reports are your contribution to +the maintenance of GNU CC. + + In order for a bug report to serve its purpose, you must include +the information that makes for fixing the bug. + +* Menu: + +* Criteria: Bug Criteria. Have you really found a bug? +* Reporting: Bug Reporting. How to report a bug effectively. + + +File: gcc.info, Node: Bug Criteria, Next: Bug Reporting, Prev: Bugs, Up: Bugs + +Have You Found a Bug? +===================== + + If you are not sure whether you have found a bug, here are some +guidelines: + + * If the compiler gets a fatal signal, for any input whatever, + that is a compiler bug. Reliable compilers never crash. + + * If the compiler produces invalid assembly code, for any input + whatever (except an `asm' statement), that is a compiler bug, + unless the compiler reports errors (not just warnings) which + would ordinarily prevent the assembler from being run. + + * If the compiler produces valid assembly code that does not + correctly execute the input source code, that is a compiler bug. + + However, you must double-check to make sure, because you may + have run into an incompatibility between GNU C and traditional C + (*note Incompatibilities::.). These incompatibilities might be + considered bugs, but they are inescapable consequences of + valuable features. + + Or you may have a program whose behavior is undefined, which + happened by chance to give the desired results with another C + compiler. + + For example, in many nonoptimizing compilers, you can write `x;' + at the end of a function instead of `return x;', with the same + results. But the value of the function is undefined if `return' + is omitted; it is not a bug when GNU CC produces different + results. + + Problems often result from expressions with two increment + operators, as in `f (*p++, *p++)'. Your previous compiler might + have interpreted that expression the way you intended; GNU CC + might interpret it another way. Neither compiler is wrong. The + bug is in your code. + + After you have localized the error to a single source line, it + should be easy to check for these things. If your program is + correct and well defined, you have found a compiler bug. + + * If the compiler produces an error message for valid input, that + is a compiler bug. + + Note that the following is not valid input, and the error + message for it is not a bug: + + int foo (char); + + int + foo (x) + char x; + { ... } + + The prototype says to pass a `char', while the definition says + to pass an `int' and treat the value as a `char'. This is what + the ANSI standard says, and it makes sense. + + * If the compiler does not produce an error message for invalid + input, that is a compiler bug. However, you should note that + your idea of "invalid input" might be my idea of "an extension" + or "support for traditional practice". + + * If you are an experienced user of C compilers, your suggestions + for improvement of GNU CC are welcome in any case. + +
\ No newline at end of file |
