1110 lines
48 KiB
Plaintext
1110 lines
48 KiB
Plaintext
This is Info file gcc.info, produced by Makeinfo-1.47 from the input
|
||
file gcc.texi.
|
||
|
||
This file documents the use and the internals of the GNU compiler.
|
||
|
||
Copyright (C) 1988, 1989, 1992 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 "Boycott"
|
||
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 "Boycott", 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: Function Attributes, Next: Function Prototypes, Prev: Case Ranges, 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 standard library functions, such as `abort' and `exit', cannot
|
||
return. GNU CC knows this automatically. Some programs define their
|
||
own functions that never return. You can declare them `volatile' to
|
||
tell the compiler this fact. For example,
|
||
|
||
extern void volatile fatal ();
|
||
|
||
void
|
||
fatal (...)
|
||
{
|
||
... /* Print error message. */ ...
|
||
exit (1);
|
||
}
|
||
|
||
The `volatile' keyword tells the compiler to assume that `fatal'
|
||
cannot return. This makes slightly better code, but more importantly
|
||
it helps avoid spurious warnings of uninitialized variables.
|
||
|
||
It does not make sense for a `volatile' function to have a return
|
||
type other than `void'.
|
||
|
||
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 int const 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'. It does not
|
||
make sense for a `const' function to return `void'.
|
||
|
||
We recommend placing the keyword `const' after the function's return
|
||
type. It makes no difference in the example above, but when the return
|
||
type is a pointer, it is the only way to make the function itself
|
||
const. For example,
|
||
|
||
const char *mincp (int);
|
||
|
||
says that `mincp' returns `const char *'--a pointer to a const object.
|
||
To declare `mincp' const, you must write this:
|
||
|
||
char * const mincp (int);
|
||
|
||
Some people object to this feature, suggesting that ANSI C's
|
||
`#pragma' should be used instead. There are two reasons for not doing
|
||
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 almost any application that might be
|
||
proposed for `#pragma'. It is basically a mistake to use `#pragma' for
|
||
*anything*.
|
||
|
||
|
||
File: gcc.info, Node: Function Prototypes, Next: Dollar Signs, Prev: Function Attributes, Up: Extensions
|
||
|
||
Prototypes and Old-Style Function Definitions
|
||
=============================================
|
||
|
||
GNU C extends ANSI C to allow a function prototype to override a
|
||
later old-style non-prototype definition. Consider the following
|
||
example:
|
||
|
||
/* Use prototypes unless the compiler is old-fashioned. */
|
||
#if __STDC__
|
||
#define P((x)) (x)
|
||
#else
|
||
#define P((x)) ()
|
||
#endif
|
||
|
||
/* Prototype function declaration. */
|
||
int isroot P((uid_t));
|
||
|
||
/* Old-style function definition. */
|
||
int
|
||
isroot (x) /* ??? lossage here ??? */
|
||
uid_t x;
|
||
{
|
||
return x == 0;
|
||
}
|
||
|
||
Suppose the type `uid_t' happens to be `short'. ANSI C does not
|
||
allow this example, because subword arguments in old-style
|
||
non-prototype definitions are promoted. Therefore in this example the
|
||
function definition's argument is really an `int', which does not match
|
||
the prototype argument type of `short'.
|
||
|
||
This restriction of ANSI C makes it hard to write code that is
|
||
portable to traditional C compilers, because the programmer does not
|
||
know whether the `uid_t' type is `short', `int', or `long'. Therefore,
|
||
in cases like these GNU C allows a prototype to override a later
|
||
old-style definition. More precisely, in GNU C, a function prototype
|
||
argument type overrides the argument type specified by a later
|
||
old-style definition if the former type is the same as the latter type
|
||
before promotion. Thus in GNU C the above example is equivalent to the
|
||
following:
|
||
|
||
int isroot (uid_t);
|
||
|
||
int
|
||
isroot (uid_t x)
|
||
{
|
||
return x == 0;
|
||
}
|
||
|
||
|
||
File: gcc.info, Node: Dollar Signs, Next: Character Escapes, Prev: Function Prototypes, 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 on certain machines if you specify
|
||
`-traditional'. On a few systems they are allowed by default, even if
|
||
`-traditional' is not used. But they are never allowed if you specify
|
||
`-ansi'.
|
||
|
||
There are certain ANSI C programs (obscure, to be sure) that would
|
||
compile incorrectly if dollar signs were permitted in identifiers. For
|
||
example:
|
||
|
||
#define foo(a) #a
|
||
#define lose(b) foo (b)
|
||
#define test$
|
||
lose (test)
|
||
|
||
|
||
File: gcc.info, Node: Character Escapes, Next: Variable Attributes, Prev: Dollar Signs, Up: Extensions
|
||
|
||
The Character ESC in Constants
|
||
==============================
|
||
|
||
You can use the sequence `\e' in a string or character constant to
|
||
stand for the ASCII character ESC.
|
||
|
||
|
||
File: gcc.info, Node: Alignment, Next: Inline, Prev: Variable Attributes, Up: Extensions
|
||
|
||
Inquiring on Alignment of Types or Variables
|
||
============================================
|
||
|
||
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: Variable Attributes, Next: Alignment, Prev: Character Escapes, Up: Extensions
|
||
|
||
Specifying Attributes of Variables
|
||
==================================
|
||
|
||
The keyword `__attribute__' allows you to specify special attributes
|
||
of variables or structure fields. The only attributes currently
|
||
defined are the `aligned' and `format' attributes.
|
||
|
||
The `aligned' attribute specifies the alignment of the variable or
|
||
structure field. For example, the declaration:
|
||
|
||
int x __attribute__ ((aligned (16))) = 0;
|
||
|
||
causes the compiler to allocate the global variable `x' on a 16-byte
|
||
boundary. On a 68000, this could be used in conjunction with an `asm'
|
||
expression to access the `move16' instruction which requires 16-byte
|
||
aligned operands.
|
||
|
||
You can also specify the alignment of structure fields. For
|
||
example, to create a double-word aligned `int' pair, you could write:
|
||
|
||
struct foo { int x[2] __attribute__ ((aligned (8))); };
|
||
|
||
This is an alternative to creating a union with a `double' member that
|
||
forces the union to be double-word aligned.
|
||
|
||
It is not possible to specify the alignment of functions; the
|
||
alignment of functions is determined by the machine's requirements and
|
||
cannot be changed. You cannot specify alignment for a typedef name
|
||
because such a name is just an alias, not a distinct type.
|
||
|
||
The `format' attribute specifies that a function takes `printf' or
|
||
`scanf' style arguments which should be type-checked against a format
|
||
string. For example, the declaration:
|
||
|
||
extern int
|
||
my_printf (void *my_object, const char *my_format, ...)
|
||
__attribute__ ((format (printf, 2, 3)));
|
||
|
||
causes the compiler to check the arguments in calls to `my_printf' for
|
||
consistency with the `printf' style format string argument `my_format'.
|
||
|
||
The first parameter of the `format' attribute determines how the
|
||
format string is interpreted, and should be either `printf' or `scanf'.
|
||
The second parameter specifies the number of the format string
|
||
argument (starting from 1). The third parameter specifies the number
|
||
of the first argument which should be checked against the format
|
||
string. For functions where the arguments are not available to be
|
||
checked (such as `vprintf'), specify the third parameter as zero. In
|
||
this case the compiler only checks the format string for consistency.
|
||
|
||
In the example above, the format string (`my_format') is the second
|
||
argument to `my_print' and the arguments to check start with the third
|
||
argument, so the correct parameters for the format attribute are 2 and
|
||
3.
|
||
|
||
The `format' attribute allows you to identify your own functions
|
||
which take format strings as arguments, so that GNU CC can check the
|
||
calls to these functions for errors. The compiler always checks
|
||
formats for the ANSI library functions `printf', `fprintf', `sprintf',
|
||
`scanf', `fscanf', `sscanf', `vprintf', `vfprintf' and `vsprintf'
|
||
whenever such warnings are requested (using `-Wformat'), so there is no
|
||
need to modify the header file `stdio.h'.
|
||
|
||
|
||
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 ten or to the maximum number of operands in any instruction pattern
|
||
in the machine description, whichever is greater.
|
||
|
||
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.
|
||
|
||
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");
|
||
|
||
If you refer to a particular hardware register from the assembler
|
||
code, then you will probably have to list the register after the third
|
||
colon to tell the compiler that the register's value is modified. In
|
||
many assemblers, the register names begin with `%'; to produce one `%'
|
||
in the assembler code, you must write `%%' in the input.
|
||
|
||
If your assembler instruction can alter the condition code register,
|
||
add `cc' to the list of clobbered registers. GNU CC on some machines
|
||
represents the condition codes as a specific hardware register; `cc'
|
||
serves to name this register. On other machines, the condition code is
|
||
handled differently, and specifying `cc' has no effect. But it is
|
||
valid no matter what the machine.
|
||
|
||
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");
|
||
|
||
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::.
|
||
|
||
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
|
||
significantly, 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))
|
||
|
||
An instruction without output operands will not be deleted or moved
|
||
significantly, regardless, unless it is unreachable.
|
||
|
||
Note that even a volatile `asm' instruction can be moved in ways
|
||
that appear insignificant to the compiler, such as across jump
|
||
instructions. You can't expect a sequence of volatile `asm'
|
||
instructions to remain perfectly consecutive. If you want consecutive
|
||
output, use a single `asm'.
|
||
|
||
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::.), if you want to
|
||
write one output of the assembler instruction directly into a
|
||
particular register. (This will work provided the register you
|
||
specify fits the constraints specified for that operand in the
|
||
`asm'.)
|
||
|
||
* Menu:
|
||
|
||
* Global Reg Vars::
|
||
* Local Reg Vars::
|
||
|
||
|
||
File: gcc.info, Node: Global Reg Vars, Next: Local 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.
|
||
|
||
On the Sparc, there are reports that g3 ... g7 are suitable
|
||
registers, but certain library functions, such as `getwd', as well as
|
||
the subroutines for division and remainder, modify g3 and g4. g1 and
|
||
g2 are local temporaries.
|
||
|
||
On the 68000, a2 ... a5 should be suitable, as should d2 ... d7. Of
|
||
course, it will not do to use more than a few of those.
|
||
|
||
|
||
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, Next: Incomplete Enums, 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
|
||
|
||
`-pedantic' causes warnings for many GNU C extensions. You can
|
||
prevent such warnings within one expression by writing `__extension__'
|
||
before the expression. `__extension__' has no effect aside from this.
|
||
|
||
|
||
File: gcc.info, Node: Incomplete Enums, Prev: Alternate Keywords, Up: Extensions
|
||
|
||
Incomplete `enum' Types
|
||
=======================
|
||
|
||
You can define an `enum' tag without specifying its possible values.
|
||
This results in an incomplete type, much like what you get if you write
|
||
`struct foo' without describing the elements. A later declaration
|
||
which does specify the possible values completes the type.
|
||
|
||
You can't allocate variables or storage using the type while it is
|
||
incomplete. However, you can work with pointers to that type.
|
||
|
||
This extension may not be very useful, but it makes the handling of
|
||
`enum' more consistent with the way `struct' and `union' are handled.
|
||
|
||
|
||
File: gcc.info, Node: Trouble, Next: Bugs, Prev: Extensions, Up: Top
|
||
|
||
Known Causes of Trouble with GNU CC
|
||
***********************************
|
||
|
||
This section describes known problems that affect users of GNU CC.
|
||
Most of these are not GNU CC bugs per se--if they were, we would fix
|
||
them. But the result for a user may be like the result of a bug.
|
||
|
||
Some of these problems are due to bugs in other software, some are
|
||
missing features that are too much work to add, and some are places
|
||
where people's opinions differ as to what is best.
|
||
|
||
* Menu:
|
||
|
||
* Actual Bugs:: Bugs we will fix later.
|
||
* Installation Problems:: Problems that manifest when you install GNU CC.
|
||
* Cross-Compiler Problems:: Common problems of cross compiling with GNU CC.
|
||
* Interoperation:: Problems using GNU CC with other compilers,
|
||
and with certain linkers, assemblers and debuggers.
|
||
* Incompatibilities:: GNU CC is incompatible with traditional C.
|
||
* Disappointments:: Regrettable things we can't change, but not quite bugs.
|
||
* Non-bugs:: Things we think are right, but some others disagree.
|
||
|
||
|
||
File: gcc.info, Node: Actual Bugs, Next: Installation Problems, Up: Trouble
|
||
|
||
Actual Bugs We Haven't Fixed Yet
|
||
================================
|
||
|
||
* Loop unrolling doesn't work properly for certain programs. This is
|
||
because of difficulty in updating the debugging information within
|
||
the loop being unrolled. We plan to revamp the representation of
|
||
debugging information so that this will work properly, but we have
|
||
not done this in version 2.2 because we don't want to delay it any
|
||
further.
|
||
|
||
* There is a bug in producing DBX output which outputs a structure
|
||
tag even when a structure doesn't have a tag. The reason we
|
||
aren't fixing this now is that a clean fix requires
|
||
reorganizations that seem risky. We will do them after 2.2 is
|
||
released.
|
||
|
||
|
||
File: gcc.info, Node: Installation Problems, Next: Cross-Compiler Problems, Prev: Actual Bugs, Up: Trouble
|
||
|
||
Installation Problems
|
||
=====================
|
||
|
||
This is a list of problems (and some apparent problems which don't
|
||
really mean anything is wrong) that show up during installation of GNU
|
||
CC.
|
||
|
||
* On certain systems, defining certain environment variables such as
|
||
`CC' can interfere with the functioning of `make'.
|
||
|
||
* If you encounter seemingly strange errors when trying to build the
|
||
compiler in a directory other than the source directory, it could
|
||
be because you have previously configured the compiler in the
|
||
source directory. Make sure you have done all the necessary
|
||
preparations. *Note Other Dir::.
|
||
|
||
* In previous versions of GNU CC, the `gcc' driver program looked for
|
||
`as' and `ld' in various places such as files beginning with
|
||
`/usr/local/lib/gcc-'. GNU CC version 2 looks for them in the
|
||
directory `/usr/local/lib/gcc-lib/TARGET/VERSION'.
|
||
|
||
Thus, to use a version of `as' or `ld' that is not the system
|
||
default, for example `gas' or GNU `ld', you must put them in that
|
||
directory (or make links to them from that directory).
|
||
|
||
* Some commands executed when making the compiler may fail (return a
|
||
non-zero status) and be ignored by `make'. These failures, which
|
||
are often due to files that were not found, are expected, and can
|
||
safely be ignored.
|
||
|
||
* It is normal to have warnings in compiling certain files about
|
||
unreachable code and about enumeration type clashes. These files'
|
||
names begin with `insn-'.
|
||
|
||
* Sometimes `make' recompiles parts of the compiler when installing
|
||
the compiler. In one case, this was traced down to a bug in
|
||
`make'. Either ignore the problem or switch to GNU Make.
|
||
|
||
* Sometimes on a Sun 4 you may observe a crash in the program
|
||
`genflags' or `genoutput' while building GCC. This is said to be
|
||
due to a bug in `sh'. You can probably get around it by running
|
||
`genflags' or `genoutput' manually and then retrying the `make'.
|
||
|
||
* On some versions of Ultrix, the system supplied compiler cannot
|
||
compile `cp-parse.c' because it cannot handle so many cases in a
|
||
`switch' statement. You can avoid this problem by specifying
|
||
`LANGUAGES=c' when you compile GNU CC with the Ultrix compiler.
|
||
Then you can compile the entire GNU compiler with GNU CC.
|
||
|
||
* If you use the 1.31 version of the MIPS assembler (such as was
|
||
shipped with Ultrix 3.1), you will need to use the
|
||
-fno-delayed-branch switch when optimizing floating point code.
|
||
Otherwise, the assembler will complain when the GCC compiler fills
|
||
a branch delay slot with a floating point instruction, such as
|
||
add.d.
|
||
|
||
* Users have reported some problems with version 2.0 of the MIPS
|
||
compiler tools that were shipped with Ultrix 4.1. Version 2.10
|
||
which came with Ultrix 4.2 seems to work fine.
|
||
|
||
* On HP 9000 series 300 or 400 running HP-UX release 8.0, there is a
|
||
bug in the assembler that must be fixed before GNU CC can be
|
||
built. This bug manifests itself during the first stage of
|
||
compilation, while building `libgcc2.a':
|
||
|
||
_floatdisf
|
||
cc1: warning: `-g' option not supported on this version of GCC
|
||
cc1: warning: `-g1' option not supported on this version of GCC
|
||
./gcc: Internal compiler error: program as got fatal signal 11
|
||
|
||
A patched version of the assembler is available by anonymous ftp
|
||
from `altdorf.ai.mit.edu' as the file
|
||
`archive/cph/hpux-8.0-assembler'. If you have HP software support,
|
||
the patch can also be obtained directly from HP, as described in
|
||
the following note:
|
||
|
||
This is the patched assembler, to patch SR#1653-010439, where
|
||
the assembler aborts on floating point constants.
|
||
|
||
The bug is not really in the assembler, but in the shared
|
||
library version of the function "cvtnum(3c)". The bug on
|
||
"cvtnum(3c)" is SR#4701-078451. Anyway, the attached
|
||
assembler uses the archive library version of "cvtnum(3c)"
|
||
and thus does not exhibit the bug.
|
||
|
||
This patch is also known as PHCO_0800.
|
||
|
||
* Another assembler problem on the HP PA results in an error message
|
||
like this while compiling part of `libgcc2.a':
|
||
|
||
as: /usr/tmp/cca08196.s @line#30 [err#1060]
|
||
Argument 1 or 3 in FARG upper
|
||
- lookahead = RTNVAL=GR
|
||
|
||
This happens because HP changed the assembler syntax after system
|
||
release 8.02. GNU CC assumes the newer syntax; if your assembler
|
||
wants the older syntax, comment out this line in the file
|
||
`pa1-hpux.h':
|
||
|
||
#define HP_FP_ARG_DESCRIPTOR_REVERSED
|
||
|
||
* Some versions of the Pyramid C compiler are reported to be unable
|
||
to compile GNU CC. You must use an older version of GNU CC for
|
||
bootstrapping. One indication of this problem is if you get a
|
||
crash when GNU CC compiles the function `muldi3' in file
|
||
`libgcc2.c'.
|
||
|
||
You may be able to succeed by getting GNU CC version 1, installing
|
||
it, and using it to compile GNU CC version 2. The bug in the
|
||
Pyramid C compiler does not seem to affect GNU CC version 1.
|
||
|
||
* On the Tower models 4N0 and 6N0, by default a process is not
|
||
allowed to have more than one megabyte of memory. GNU CC cannot
|
||
compile itself (or many other programs) with `-O' in that much
|
||
memory.
|
||
|
||
To solve this problem, reconfigure the kernel adding the following
|
||
line to the configuration file:
|
||
|
||
MAXUMEM = 4096
|
||
|
||
* On the Altos 3068, programs compiled with GNU CC won't work unless
|
||
you fix a kernel bug. This happens using system versions V.2.2
|
||
1.0gT1 and V.2.2 1.0e and perhaps later versions as well. See the
|
||
file `README.ALTOS'.
|
||
|
||
|
||
File: gcc.info, Node: Cross-Compiler Problems, Next: Interoperation, Prev: Installation Problems, Up: Trouble
|
||
|
||
Cross-Compiler Problems
|
||
=======================
|
||
|
||
* Cross compilation can run into trouble for certain machines because
|
||
some target machines' assemblers require floating point numbers to
|
||
be written as *integer* constants in certain contexts.
|
||
|
||
The compiler writes these integer constants by examining the
|
||
floating point value as an integer and printing that integer,
|
||
because this is simple to write and independent of the details of
|
||
the floating point representation. But this does not work if the
|
||
compiler is running on a different machine with an incompatible
|
||
floating point format, or even a different byte-ordering.
|
||
|
||
In addition, correct constant folding of floating point values
|
||
requires representing them in the target machine's format. (The C
|
||
standard does not quite require this, but in practice it is the
|
||
only way to win.)
|
||
|
||
It is now possible to overcome these problems by defining macros
|
||
such as `REAL_VALUE_TYPE'. But doing so is a substantial amount of
|
||
work for each target machine. *Note Cross-compilation::.
|
||
|
||
* At present, the program `mips-tfile' which adds debug support to
|
||
object files on MIPS systems does not work in a cross compile
|
||
environment.
|
||
|
||
|
||
File: gcc.info, Node: Interoperation, Next: Incompatibilities, Prev: Cross-Compiler Problems, Up: Trouble
|
||
|
||
Interoperation
|
||
==============
|
||
|
||
This section lists various difficulties encountered in using GNU C or
|
||
GNU C++ together with other compilers or with the assemblers, linkers
|
||
and debuggers on certain systems.
|
||
|
||
* GNU C normally compiles functions to return small structures and
|
||
unions in registers. Most other compilers arrange to return them
|
||
just like larger structures and unions. This can lead to trouble
|
||
when you link together code compiled by different compilers. To
|
||
avoid the problem, you can use the option `-fpcc-struct-value'
|
||
when compiling with GNU CC.
|
||
|
||
* GNU C++ does not do name mangling in the same way as other C++
|
||
compilers. This means that object files compiled with one compiler
|
||
cannot be used with another.
|
||
|
||
GNU C++ also uses different techniques for arranging virtual
|
||
function tables and the layout of class instances. In general,
|
||
therefore, linking code compiled with different C++ compilers does
|
||
not work.
|
||
|
||
* Older GDB versions sometimes fail to read the output of GNU CC
|
||
version 2. If you have trouble, get GDB version 4.4 or later.
|
||
|
||
* DBX rejects some files produced by GNU CC, though it accepts
|
||
similar constructs in output from PCC. Until someone can supply a
|
||
coherent description of what is valid DBX input and what is not,
|
||
there is nothing I can do about these problems. You are on your
|
||
own.
|
||
|
||
* The GNU assembler (GAS) does not support PIC. To generate PIC
|
||
code, you must use some other assembler, such as `/bin/as'.
|
||
|
||
* On some BSD systems including some versions of Ultrix, use of
|
||
profiling causes static variable destructors (currently used only
|
||
in C++) not to be run.
|
||
|
||
* On a Sun, linking using GNU CC fails to find a shared library and
|
||
reports that the library doesn't exist at all.
|
||
|
||
This happens if you are using the GNU linker, because it does only
|
||
static linking and looks only for unshared libraries. If you have
|
||
a shared library with no unshared counterpart, the GNU linker
|
||
won't find anything.
|
||
|
||
We hope to make a linker which supports Sun shared libraries, but
|
||
please don't ask when it will be finished--we don't know.
|
||
|
||
* Sun forgot to include a static version of `libdl.a' with some
|
||
versions of SunOS (mainly 4.1). This results in undefined symbols
|
||
when linking static binaries (that is, if you use `-static'). If
|
||
you see undefined symbols `_dlclose', `_dlsym' or `_dlopen' when
|
||
linking, compile and link against the file `mit/util/misc/dlsym.c'
|
||
from the MIT version of X windows.
|
||
|
||
* On the HP PA machine, ADB sometimes fails to work on functions
|
||
compiled with GNU CC. Specifically, it fails to work on functions
|
||
that use `alloca' or variable-size arrays. This is because GNU CC
|
||
doesn't generate HPUX unwind descriptors for such functions. It
|
||
may even be impossible to generate them.
|
||
|
||
* Profiling is not supported on the HP PA machine. Neither is
|
||
debugging (`-g'), unless you use the preliminary GNU tools (*note
|
||
Installation::.).
|
||
|
||
* GNU CC on the HP PA handles variadic function arguments using a
|
||
calling convention incompatible with the HP compiler. This is
|
||
only a problem for routines that take `va_list' as parameters,
|
||
such as `vprintf'. This may be fixed eventually.
|
||
|
||
* The current version of the assembler (`/bin/as') for the RS/6000
|
||
has certain problems that prevent the `-g' option in GCC from
|
||
working.
|
||
|
||
IBM has produced a fixed version of the assembler. The replacement
|
||
assembler is not a standard component of either AIX 3.1.5 or AIX
|
||
3.2, but is expected to become standard in a future distribution.
|
||
This assembler is available from IBM as APAR IX22829. Yet more
|
||
bugs have been fixed in a newer assembler, which will shortly be
|
||
available as APAR IX26107. See the file `README.RS6000' for more
|
||
details on these assemblers.
|
||
|
||
* On the IBM RS/6000, compiling code of the form
|
||
|
||
extern int foo;
|
||
|
||
... foo ...
|
||
|
||
static int foo;
|
||
|
||
will cause the linker to report an undefined symbol `foo'.
|
||
Although this behavior differs from most other systems, it is not a
|
||
bug because redefining an `extern' variable as `static' is
|
||
undefined in ANSI C.
|
||
|
||
* On VMS, GAS versions 1.38.1 and earlier may cause spurious warning
|
||
messages from the linker. These warning messages complain of
|
||
mismatched psect attributes. You can ignore them. *Note VMS
|
||
Install::.
|
||
|
||
* On the Alliant, the system's own convention for returning
|
||
structures and unions is unusual, and is not compatible with GNU
|
||
CC no matter what options are used.
|
||
|
||
* On the IBM RT PC, the MetaWare HighC compiler (hc) uses yet another
|
||
convention for structure and union returning. Use
|
||
`-mhc-struct-return' to tell GNU CC to use a convention compatible
|
||
with it.
|
||
|
||
* On Ultrix, the Fortran compiler expects registers 2 through 5 to
|
||
be saved by function calls. However, the C compiler uses
|
||
conventions compatible with BSD Unix: registers 2 through 5 may be
|
||
clobbered by function calls.
|
||
|
||
GNU CC uses the same convention as the Ultrix C compiler. You can
|
||
use these options to produce code compatible with the Fortran
|
||
compiler:
|
||
|
||
-fcall-saved-r2 -fcall-saved-r3 -fcall-saved-r4 -fcall-saved-r5
|
||
|
||
|