mirror of
https://github.com/pmret/gcc-papermario.git
synced 2024-11-09 20:32:32 +01:00
1094 lines
48 KiB
Plaintext
1094 lines
48 KiB
Plaintext
|
This is Info file gcc.info, produced by Makeinfo version 1.67 from the
|
|||
|
input file gcc.texi.
|
|||
|
|
|||
|
This file documents the use and the internals of the GNU compiler.
|
|||
|
|
|||
|
Published by the Free Software Foundation 59 Temple Place - Suite 330
|
|||
|
Boston, MA 02111-1307 USA
|
|||
|
|
|||
|
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
|||
|
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," "Funding for
|
|||
|
Free Software," 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," "Funding for Free Software," 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: Inline, Next: Extended Asm, Prev: Alignment, Up: C 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. The effect on code size is
|
|||
|
less predictable; object code may be larger or smaller with function
|
|||
|
inlining, depending on the particular case. Inlining of functions is an
|
|||
|
optimization and it really "works" only in optimizing compilation. If
|
|||
|
you don't use `-O', no function is really inline.
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
Note that in C and Objective C, unlike C++, the `inline' keyword
|
|||
|
does not affect the linkage of the function.
|
|||
|
|
|||
|
GNU CC automatically inlines member functions defined within the
|
|||
|
class body of C++ programs even if they are not explicitly declared
|
|||
|
`inline'. (You can override this with `-fno-default-inline'; *note
|
|||
|
Options Controlling C++ Dialect: C++ Dialect Options..)
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
GNU C does not inline any functions when not optimizing. It is not
|
|||
|
clear whether it is better to inline or not, in this case, but we found
|
|||
|
that a correct implementation when not optimizing was difficult. So we
|
|||
|
did the easy thing, and turned it off.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Extended Asm, Next: Asm Labels, Prev: Inline, Up: C Extensions
|
|||
|
|
|||
|
Assembler Instructions with C Expression Operands
|
|||
|
=================================================
|
|||
|
|
|||
|
In an assembler instruction using `asm', you can specify the
|
|||
|
operands of the instruction using C expressions. This means you need
|
|||
|
not guess 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 the
|
|||
|
operands within each group. 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 but there are input operands, you
|
|||
|
must place 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 even whether it is valid
|
|||
|
assembler input. The extended `asm' feature is most often used for
|
|||
|
machine instructions the compiler itself does not know exist. If the
|
|||
|
output expression cannot be directly addressed (for example, it is a
|
|||
|
bit field), your constraint must allow a register. In that case, GNU CC
|
|||
|
will use the register as the output of the `asm', and then store that
|
|||
|
register into the output.
|
|||
|
|
|||
|
The ordinary 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 supports input-output or read-write
|
|||
|
operands. Use the constraint character `+' to indicate such an operand
|
|||
|
and list it with the output operands.
|
|||
|
|
|||
|
When the constraints for the read-write operand (or the operand in
|
|||
|
which only some of the bits are to be changed) allows a register, you
|
|||
|
may, as an alternative, 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 reliably:
|
|||
|
|
|||
|
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, you will probably have to list the register after the third colon
|
|||
|
to tell the compiler the register's value is modified. In some
|
|||
|
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.
|
|||
|
|
|||
|
If your assembler instruction modifies memory in an unpredictable
|
|||
|
fashion, add `memory' to the list of clobbered registers. This will
|
|||
|
cause GNU CC to not keep memory values cached in registers across the
|
|||
|
assembler instruction.
|
|||
|
|
|||
|
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 most 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 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 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.
|
|||
|
|
|||
|
Speaking of labels, jumps from one `asm' to another are not
|
|||
|
supported. The compiler's optimizers do not know about these jumps, and
|
|||
|
therefore they cannot take account of them when deciding how to
|
|||
|
optimize.
|
|||
|
|
|||
|
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 the instruction has no side effects except to change the output
|
|||
|
operands. This does not mean 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 get_and_set_priority(new) \
|
|||
|
({ int __old; \
|
|||
|
asm volatile ("get_and_set_priority %0, %1": "=g" (__old) : "g" (new)); \
|
|||
|
__old; })
|
|||
|
b
|
|||
|
|
|||
|
If you write an `asm' instruction with no outputs, GNU CC will know the
|
|||
|
instruction has side-effects and will not delete the instruction or
|
|||
|
move it outside of loops. If the side-effects of your instruction are
|
|||
|
not purely external, but will affect variables in your program in ways
|
|||
|
other than reading the inputs and clobbering the specified registers or
|
|||
|
memory, you should write the `volatile' keyword to prevent future
|
|||
|
versions of GNU CC from moving the instruction around within a core
|
|||
|
region.
|
|||
|
|
|||
|
An `asm' instruction without any operands or clobbers (and "old
|
|||
|
style" `asm') will not be deleted or moved significantly, regardless,
|
|||
|
unless it is unreachable, the same wasy as if you had written a
|
|||
|
`volatile' keyword.
|
|||
|
|
|||
|
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: C 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: C 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'.
|
|||
|
|
|||
|
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; excessive use of this feature
|
|||
|
leaves the compiler too few available registers to compile certain
|
|||
|
functions.
|
|||
|
|
|||
|
This option does not guarantee that GNU CC will generate code that
|
|||
|
has this variable in the register you specify at all times. You may not
|
|||
|
code an explicit reference to this register in an `asm' statement and
|
|||
|
assume it will always refer to this variable.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Alternate Keywords, Next: Incomplete Enums, Prev: Explicit Reg Vars, Up: C 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, Next: Function Names, Prev: Alternate Keywords, Up: C 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.
|
|||
|
|
|||
|
This extension is not supported by GNU C++.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Function Names, Next: Return Address, Prev: Incomplete Enums, Up: C Extensions
|
|||
|
|
|||
|
Function Names as Strings
|
|||
|
=========================
|
|||
|
|
|||
|
GNU CC predefines two string variables to be the name of the current
|
|||
|
function. The variable `__FUNCTION__' is the name of the function as
|
|||
|
it appears in the source. The variable `__PRETTY_FUNCTION__' is the
|
|||
|
name of the function pretty printed in a language specific fashion.
|
|||
|
|
|||
|
These names are always the same in a C function, but in a C++
|
|||
|
function they may be different. For example, this program:
|
|||
|
|
|||
|
extern "C" {
|
|||
|
extern int printf (char *, ...);
|
|||
|
}
|
|||
|
|
|||
|
class a {
|
|||
|
public:
|
|||
|
sub (int i)
|
|||
|
{
|
|||
|
printf ("__FUNCTION__ = %s\n", __FUNCTION__);
|
|||
|
printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
int
|
|||
|
main (void)
|
|||
|
{
|
|||
|
a ax;
|
|||
|
ax.sub (0);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
gives this output:
|
|||
|
|
|||
|
__FUNCTION__ = sub
|
|||
|
__PRETTY_FUNCTION__ = int a::sub (int)
|
|||
|
|
|||
|
These names are not macros: they are predefined string variables.
|
|||
|
For example, `#ifdef __FUNCTION__' does not have any special meaning
|
|||
|
inside a function, since the preprocessor does not do anything special
|
|||
|
with the identifier `__FUNCTION__'.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Return Address, Prev: Function Names, Up: C Extensions
|
|||
|
|
|||
|
Getting the Return or Frame Address of a Function
|
|||
|
=================================================
|
|||
|
|
|||
|
These functions may be used to get information about the callers of a
|
|||
|
function.
|
|||
|
|
|||
|
`__builtin_return_address (LEVEL)'
|
|||
|
This function returns the return address of the current function,
|
|||
|
or of one of its callers. The LEVEL argument is number of frames
|
|||
|
to scan up the call stack. A value of `0' yields the return
|
|||
|
address of the current function, a value of `1' yields the return
|
|||
|
address of the caller of the current function, and so forth.
|
|||
|
|
|||
|
The LEVEL argument must be a constant integer.
|
|||
|
|
|||
|
On some machines it may be impossible to determine the return
|
|||
|
address of any function other than the current one; in such cases,
|
|||
|
or when the top of the stack has been reached, this function will
|
|||
|
return `0'.
|
|||
|
|
|||
|
This function should only be used with a non-zero argument for
|
|||
|
debugging purposes.
|
|||
|
|
|||
|
`__builtin_frame_address (LEVEL)'
|
|||
|
This function is similar to `__builtin_return_address', but it
|
|||
|
returns the address of the function frame rather than the return
|
|||
|
address of the function. Calling `__builtin_frame_address' with a
|
|||
|
value of `0' yields the frame address of the current function, a
|
|||
|
value of `1' yields the frame address of the caller of the current
|
|||
|
function, and so forth.
|
|||
|
|
|||
|
The frame is the area on the stack which holds local variables and
|
|||
|
saved registers. The frame address is normally the address of the
|
|||
|
first word pushed on to the stack by the function. However, the
|
|||
|
exact definition depends upon the processor and the calling
|
|||
|
convention. If the processor has a dedicated frame pointer
|
|||
|
register, and the function has a frame, then
|
|||
|
`__builtin_frame_address' will return the value of the frame
|
|||
|
pointer register.
|
|||
|
|
|||
|
The caveats that apply to `__builtin_return_address' apply to this
|
|||
|
function as well.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: C++ Extensions, Next: Gcov, Prev: C Extensions, Up: Top
|
|||
|
|
|||
|
Extensions to the C++ Language
|
|||
|
******************************
|
|||
|
|
|||
|
The GNU compiler provides these extensions to the C++ language (and
|
|||
|
you can also use most of the C language extensions in your C++
|
|||
|
programs). If you want to write code that checks whether these
|
|||
|
features are available, you can test for the GNU compiler the same way
|
|||
|
as for C programs: check for a predefined macro `__GNUC__'. You can
|
|||
|
also use `__GNUG__' to test specifically for GNU C++ (*note Standard
|
|||
|
Predefined Macros: (cpp.info)Standard Predefined.).
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Naming Results:: Giving a name to C++ function return values.
|
|||
|
* Min and Max:: C++ Minimum and maximum operators.
|
|||
|
* Destructors and Goto:: Goto is safe to use in C++ even when destructors
|
|||
|
are needed.
|
|||
|
* C++ Interface:: You can use a single C++ header file for both
|
|||
|
declarations and definitions.
|
|||
|
* Template Instantiation:: Methods for ensuring that exactly one copy of
|
|||
|
each needed template instantiation is emitted.
|
|||
|
* C++ Signatures:: You can specify abstract types to get subtype
|
|||
|
polymorphism independent from inheritance.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Naming Results, Next: Min and Max, Up: C++ Extensions
|
|||
|
|
|||
|
Named Return Values in C++
|
|||
|
==========================
|
|||
|
|
|||
|
GNU C++ extends the function-definition syntax to allow you to
|
|||
|
specify a name for the result of a function outside the body of the
|
|||
|
definition, in C++ programs:
|
|||
|
|
|||
|
TYPE
|
|||
|
FUNCTIONNAME (ARGS) return RESULTNAME;
|
|||
|
{
|
|||
|
...
|
|||
|
BODY
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
You can use this feature to avoid an extra constructor call when a
|
|||
|
function result has a class type. For example, consider a function
|
|||
|
`m', declared as `X v = m ();', whose result is of class `X':
|
|||
|
|
|||
|
X
|
|||
|
m ()
|
|||
|
{
|
|||
|
X b;
|
|||
|
b.a = 23;
|
|||
|
return b;
|
|||
|
}
|
|||
|
|
|||
|
Although `m' appears to have no arguments, in fact it has one
|
|||
|
implicit argument: the address of the return value. At invocation, the
|
|||
|
address of enough space to hold `v' is sent in as the implicit argument.
|
|||
|
Then `b' is constructed and its `a' field is set to the value 23.
|
|||
|
Finally, a copy constructor (a constructor of the form `X(X&)') is
|
|||
|
applied to `b', with the (implicit) return value location as the
|
|||
|
target, so that `v' is now bound to the return value.
|
|||
|
|
|||
|
But this is wasteful. The local `b' is declared just to hold
|
|||
|
something that will be copied right out. While a compiler that
|
|||
|
combined an "elision" algorithm with interprocedural data flow analysis
|
|||
|
could conceivably eliminate all of this, it is much more practical to
|
|||
|
allow you to assist the compiler in generating efficient code by
|
|||
|
manipulating the return value explicitly, thus avoiding the local
|
|||
|
variable and copy constructor altogether.
|
|||
|
|
|||
|
Using the extended GNU C++ function-definition syntax, you can avoid
|
|||
|
the temporary allocation and copying by naming `r' as your return value
|
|||
|
at the outset, and assigning to its `a' field directly:
|
|||
|
|
|||
|
X
|
|||
|
m () return r;
|
|||
|
{
|
|||
|
r.a = 23;
|
|||
|
}
|
|||
|
|
|||
|
The declaration of `r' is a standard, proper declaration, whose effects
|
|||
|
are executed *before* any of the body of `m'.
|
|||
|
|
|||
|
Functions of this type impose no additional restrictions; in
|
|||
|
particular, you can execute `return' statements, or return implicitly by
|
|||
|
reaching the end of the function body ("falling off the edge"). Cases
|
|||
|
like
|
|||
|
|
|||
|
X
|
|||
|
m () return r (23);
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
(or even `X m () return r (23); { }') are unambiguous, since the return
|
|||
|
value `r' has been initialized in either case. The following code may
|
|||
|
be hard to read, but also works predictably:
|
|||
|
|
|||
|
X
|
|||
|
m () return r;
|
|||
|
{
|
|||
|
X b;
|
|||
|
return b;
|
|||
|
}
|
|||
|
|
|||
|
The return value slot denoted by `r' is initialized at the outset,
|
|||
|
but the statement `return b;' overrides this value. The compiler deals
|
|||
|
with this by destroying `r' (calling the destructor if there is one, or
|
|||
|
doing nothing if there is not), and then reinitializing `r' with `b'.
|
|||
|
|
|||
|
This extension is provided primarily to help people who use
|
|||
|
overloaded operators, where there is a great need to control not just
|
|||
|
the arguments, but the return values of functions. For classes where
|
|||
|
the copy constructor incurs a heavy performance penalty (especially in
|
|||
|
the common case where there is a quick default constructor), this is a
|
|||
|
major savings. The disadvantage of this extension is that you do not
|
|||
|
control when the default constructor for the return value is called: it
|
|||
|
is always called at the beginning.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Min and Max, Next: Destructors and Goto, Prev: Naming Results, Up: C++ Extensions
|
|||
|
|
|||
|
Minimum and Maximum Operators in C++
|
|||
|
====================================
|
|||
|
|
|||
|
It is very convenient to have operators which return the "minimum"
|
|||
|
or the "maximum" of two arguments. In GNU C++ (but not in GNU C),
|
|||
|
|
|||
|
`A <? B'
|
|||
|
is the "minimum", returning the smaller of the numeric values A
|
|||
|
and B;
|
|||
|
|
|||
|
`A >? B'
|
|||
|
is the "maximum", returning the larger of the numeric values A and
|
|||
|
B.
|
|||
|
|
|||
|
These operations are not primitive in ordinary C++, since you can
|
|||
|
use a macro to return the minimum of two things in C++, as in the
|
|||
|
following example.
|
|||
|
|
|||
|
#define MIN(X,Y) ((X) < (Y) ? : (X) : (Y))
|
|||
|
|
|||
|
You might then use `int min = MIN (i, j);' to set MIN to the minimum
|
|||
|
value of variables I and J.
|
|||
|
|
|||
|
However, side effects in `X' or `Y' may cause unintended behavior.
|
|||
|
For example, `MIN (i++, j++)' will fail, incrementing the smaller
|
|||
|
counter twice. A GNU C extension allows you to write safe macros that
|
|||
|
avoid this kind of problem (*note Naming an Expression's Type: Naming
|
|||
|
Types.). However, writing `MIN' and `MAX' as macros also forces you to
|
|||
|
use function-call notation for a fundamental arithmetic operation.
|
|||
|
Using GNU C++ extensions, you can write `int min = i <? j;' instead.
|
|||
|
|
|||
|
Since `<?' and `>?' are built into the compiler, they properly
|
|||
|
handle expressions with side-effects; `int min = i++ <? j++;' works
|
|||
|
correctly.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Destructors and Goto, Next: C++ Interface, Prev: Min and Max, Up: C++ Extensions
|
|||
|
|
|||
|
`goto' and Destructors in GNU C++
|
|||
|
=================================
|
|||
|
|
|||
|
In C++ programs, you can safely use the `goto' statement. When you
|
|||
|
use it to exit a block which contains aggregates requiring destructors,
|
|||
|
the destructors will run before the `goto' transfers control.
|
|||
|
|
|||
|
The compiler still forbids using `goto' to *enter* a scope that
|
|||
|
requires constructors.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: C++ Interface, Next: Template Instantiation, Prev: Destructors and Goto, Up: C++ Extensions
|
|||
|
|
|||
|
Declarations and Definitions in One Header
|
|||
|
==========================================
|
|||
|
|
|||
|
C++ object definitions can be quite complex. In principle, your
|
|||
|
source code will need two kinds of things for each object that you use
|
|||
|
across more than one source file. First, you need an "interface"
|
|||
|
specification, describing its structure with type declarations and
|
|||
|
function prototypes. Second, you need the "implementation" itself. It
|
|||
|
can be tedious to maintain a separate interface description in a header
|
|||
|
file, in parallel to the actual implementation. It is also dangerous,
|
|||
|
since separate interface and implementation definitions may not remain
|
|||
|
parallel.
|
|||
|
|
|||
|
With GNU C++, you can use a single header file for both purposes.
|
|||
|
|
|||
|
*Warning:* The mechanism to specify this is in transition. For the
|
|||
|
nonce, you must use one of two `#pragma' commands; in a future
|
|||
|
release of GNU C++, an alternative mechanism will make these
|
|||
|
`#pragma' commands unnecessary.
|
|||
|
|
|||
|
The header file contains the full definitions, but is marked with
|
|||
|
`#pragma interface' in the source code. This allows the compiler to
|
|||
|
use the header file only as an interface specification when ordinary
|
|||
|
source files incorporate it with `#include'. In the single source file
|
|||
|
where the full implementation belongs, you can use either a naming
|
|||
|
convention or `#pragma implementation' to indicate this alternate use
|
|||
|
of the header file.
|
|||
|
|
|||
|
`#pragma interface'
|
|||
|
`#pragma interface "SUBDIR/OBJECTS.h"'
|
|||
|
Use this directive in *header files* that define object classes,
|
|||
|
to save space in most of the object files that use those classes.
|
|||
|
Normally, local copies of certain information (backup copies of
|
|||
|
inline member functions, debugging information, and the internal
|
|||
|
tables that implement virtual functions) must be kept in each
|
|||
|
object file that includes class definitions. You can use this
|
|||
|
pragma to avoid such duplication. When a header file containing
|
|||
|
`#pragma interface' is included in a compilation, this auxiliary
|
|||
|
information will not be generated (unless the main input source
|
|||
|
file itself uses `#pragma implementation'). Instead, the object
|
|||
|
files will contain references to be resolved at link time.
|
|||
|
|
|||
|
The second form of this directive is useful for the case where you
|
|||
|
have multiple headers with the same name in different directories.
|
|||
|
If you use this form, you must specify the same string to `#pragma
|
|||
|
implementation'.
|
|||
|
|
|||
|
`#pragma implementation'
|
|||
|
`#pragma implementation "OBJECTS.h"'
|
|||
|
Use this pragma in a *main input file*, when you want full output
|
|||
|
from included header files to be generated (and made globally
|
|||
|
visible). The included header file, in turn, should use `#pragma
|
|||
|
interface'. Backup copies of inline member functions, debugging
|
|||
|
information, and the internal tables used to implement virtual
|
|||
|
functions are all generated in implementation files.
|
|||
|
|
|||
|
If you use `#pragma implementation' with no argument, it applies to
|
|||
|
an include file with the same basename(1) as your source file.
|
|||
|
For example, in `allclass.cc', giving just `#pragma implementation'
|
|||
|
by itself is equivalent to `#pragma implementation "allclass.h"'.
|
|||
|
|
|||
|
In versions of GNU C++ prior to 2.6.0 `allclass.h' was treated as
|
|||
|
an implementation file whenever you would include it from
|
|||
|
`allclass.cc' even if you never specified `#pragma
|
|||
|
implementation'. This was deemed to be more trouble than it was
|
|||
|
worth, however, and disabled.
|
|||
|
|
|||
|
If you use an explicit `#pragma implementation', it must appear in
|
|||
|
your source file *before* you include the affected header files.
|
|||
|
|
|||
|
Use the string argument if you want a single implementation file to
|
|||
|
include code from multiple header files. (You must also use
|
|||
|
`#include' to include the header file; `#pragma implementation'
|
|||
|
only specifies how to use the file--it doesn't actually include
|
|||
|
it.)
|
|||
|
|
|||
|
There is no way to split up the contents of a single header file
|
|||
|
into multiple implementation files.
|
|||
|
|
|||
|
`#pragma implementation' and `#pragma interface' also have an effect
|
|||
|
on function inlining.
|
|||
|
|
|||
|
If you define a class in a header file marked with `#pragma
|
|||
|
interface', the effect on a function defined in that class is similar to
|
|||
|
an explicit `extern' declaration--the compiler emits no code at all to
|
|||
|
define an independent version of the function. Its definition is used
|
|||
|
only for inlining with its callers.
|
|||
|
|
|||
|
Conversely, when you include the same header file in a main source
|
|||
|
file that declares it as `#pragma implementation', the compiler emits
|
|||
|
code for the function itself; this defines a version of the function
|
|||
|
that can be found via pointers (or by callers compiled without
|
|||
|
inlining). If all calls to the function can be inlined, you can avoid
|
|||
|
emitting the function by compiling with `-fno-implement-inlines'. If
|
|||
|
any calls were not inlined, you will get linker errors.
|
|||
|
|
|||
|
---------- Footnotes ----------
|
|||
|
|
|||
|
(1) A file's "basename" was the name stripped of all leading path
|
|||
|
information and of trailing suffixes, such as `.h' or `.C' or `.cc'.
|
|||
|
|
|||
|
|
|||
|
File: gcc.info, Node: Template Instantiation, Next: C++ Signatures, Prev: C++ Interface, Up: C++ Extensions
|
|||
|
|
|||
|
Where's the Template?
|
|||
|
=====================
|
|||
|
|
|||
|
C++ templates are the first language feature to require more
|
|||
|
intelligence from the environment than one usually finds on a UNIX
|
|||
|
system. Somehow the compiler and linker have to make sure that each
|
|||
|
template instance occurs exactly once in the executable if it is needed,
|
|||
|
and not at all otherwise. There are two basic approaches to this
|
|||
|
problem, which I will refer to as the Borland model and the Cfront
|
|||
|
model.
|
|||
|
|
|||
|
Borland model
|
|||
|
Borland C++ solved the template instantiation problem by adding
|
|||
|
the code equivalent of common blocks to their linker; the compiler
|
|||
|
emits template instances in each translation unit that uses them,
|
|||
|
and the linker collapses them together. The advantage of this
|
|||
|
model is that the linker only has to consider the object files
|
|||
|
themselves; there is no external complexity to worry about. This
|
|||
|
disadvantage is that compilation time is increased because the
|
|||
|
template code is being compiled repeatedly. Code written for this
|
|||
|
model tends to include definitions of all templates in the header
|
|||
|
file, since they must be seen to be instantiated.
|
|||
|
|
|||
|
Cfront model
|
|||
|
The AT&T C++ translator, Cfront, solved the template instantiation
|
|||
|
problem by creating the notion of a template repository, an
|
|||
|
automatically maintained place where template instances are
|
|||
|
stored. A more modern version of the repository works as follows:
|
|||
|
As individual object files are built, the compiler places any
|
|||
|
template definitions and instantiations encountered in the
|
|||
|
repository. At link time, the link wrapper adds in the objects in
|
|||
|
the repository and compiles any needed instances that were not
|
|||
|
previously emitted. The advantages of this model are more optimal
|
|||
|
compilation speed and the ability to use the system linker; to
|
|||
|
implement the Borland model a compiler vendor also needs to
|
|||
|
replace the linker. The disadvantages are vastly increased
|
|||
|
complexity, and thus potential for error; for some code this can be
|
|||
|
just as transparent, but in practice it can been very difficult to
|
|||
|
build multiple programs in one directory and one program in
|
|||
|
multiple directories. Code written for this model tends to
|
|||
|
separate definitions of non-inline member templates into a
|
|||
|
separate file, which should be compiled separately.
|
|||
|
|
|||
|
When used with GNU ld version 2.8 or later on an ELF system such as
|
|||
|
Linux/GNU or Solaris 2, or on Microsoft Windows, g++ supports the
|
|||
|
Borland model. On other systems, g++ implements neither automatic
|
|||
|
model.
|
|||
|
|
|||
|
A future version of g++ will support a hybrid model whereby the
|
|||
|
compiler will emit any instantiations for which the template definition
|
|||
|
is included in the compile, and store template definitions and
|
|||
|
instantiation context information into the object file for the rest.
|
|||
|
The link wrapper will extract that information as necessary and invoke
|
|||
|
the compiler to produce the remaining instantiations. The linker will
|
|||
|
then combine duplicate instantiations.
|
|||
|
|
|||
|
In the mean time, you have the following options for dealing with
|
|||
|
template instantiations:
|
|||
|
|
|||
|
1. Compile your code with `-fno-implicit-templates' to disable the
|
|||
|
implicit generation of template instances, and explicitly
|
|||
|
instantiate all the ones you use. This approach requires more
|
|||
|
knowledge of exactly which instances you need than do the others,
|
|||
|
but it's less mysterious and allows greater control. You can
|
|||
|
scatter the explicit instantiations throughout your program,
|
|||
|
perhaps putting them in the translation units where the instances
|
|||
|
are used or the translation units that define the templates
|
|||
|
themselves; you can put all of the explicit instantiations you
|
|||
|
need into one big file; or you can create small files like
|
|||
|
|
|||
|
#include "Foo.h"
|
|||
|
#include "Foo.cc"
|
|||
|
|
|||
|
template class Foo<int>;
|
|||
|
template ostream& operator <<
|
|||
|
(ostream&, const Foo<int>&);
|
|||
|
|
|||
|
for each of the instances you need, and create a template
|
|||
|
instantiation library from those.
|
|||
|
|
|||
|
If you are using Cfront-model code, you can probably get away with
|
|||
|
not using `-fno-implicit-templates' when compiling files that don't
|
|||
|
`#include' the member template definitions.
|
|||
|
|
|||
|
If you use one big file to do the instantiations, you may want to
|
|||
|
compile it without `-fno-implicit-templates' so you get all of the
|
|||
|
instances required by your explicit instantiations (but not by any
|
|||
|
other files) without having to specify them as well.
|
|||
|
|
|||
|
g++ has extended the template instantiation syntax outlined in the
|
|||
|
Working Paper to allow forward declaration of explicit
|
|||
|
instantiations, explicit instantiation of members of template
|
|||
|
classes and instantiation of the compiler support data for a
|
|||
|
template class (i.e. the vtable) without instantiating any of its
|
|||
|
members:
|
|||
|
|
|||
|
extern template int max (int, int);
|
|||
|
template void Foo<int>::f ();
|
|||
|
inline template class Foo<int>;
|
|||
|
|
|||
|
2. Do nothing. Pretend g++ does implement automatic instantiation
|
|||
|
management. Code written for the Borland model will work fine, but
|
|||
|
each translation unit will contain instances of each of the
|
|||
|
templates it uses. In a large program, this can lead to an
|
|||
|
unacceptable amount of code duplication.
|
|||
|
|
|||
|
3. Add `#pragma interface' to all files containing template
|
|||
|
definitions. For each of these files, add `#pragma implementation
|
|||
|
"FILENAME"' to the top of some `.C' file which `#include's it.
|
|||
|
Then compile everything with `-fexternal-templates'. The
|
|||
|
templates will then only be expanded in the translation unit which
|
|||
|
implements them (i.e. has a `#pragma implementation' line for the
|
|||
|
file where they live); all other files will use external
|
|||
|
references. If you're lucky, everything should work properly. If
|
|||
|
you get undefined symbol errors, you need to make sure that each
|
|||
|
template instance which is used in the program is used in the file
|
|||
|
which implements that template. If you don't have any use for a
|
|||
|
particular instance in that file, you can just instantiate it
|
|||
|
explicitly, using the syntax from the latest C++ working paper:
|
|||
|
|
|||
|
template class A<int>;
|
|||
|
template ostream& operator << (ostream&, const A<int>&);
|
|||
|
|
|||
|
This strategy will work with code written for either model. If
|
|||
|
you are using code written for the Cfront model, the file
|
|||
|
containing a class template and the file containing its member
|
|||
|
templates should be implemented in the same translation unit.
|
|||
|
|
|||
|
A slight variation on this approach is to instead use the flag
|
|||
|
`-falt-external-templates'; this flag causes template instances to
|
|||
|
be emitted in the translation unit that implements the header
|
|||
|
where they are first instantiated, rather than the one which
|
|||
|
implements the file where the templates are defined. This header
|
|||
|
must be the same in all translation units, or things are likely to
|
|||
|
break.
|
|||
|
|
|||
|
*Note Declarations and Definitions in One Header: C++ Interface,
|
|||
|
for more discussion of these pragmas.
|
|||
|
|