home *** CD-ROM | disk | FTP | other *** search
GNU Info File | 1995-11-26 | 37.4 KB | 870 lines |
- This is Info file gcc.info, produced by Makeinfo-1.55 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 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: 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'.
-
- 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: 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, 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: C++ Extensions, Next: Trouble, 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 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. (In ANSI
- C++, `goto' is restricted to targets within the current block.)
-
- 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', `#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; template
- instances are emitted in each translation unit that uses them, and
- they are collapsed together at run time. 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 member templates in the
- header file, since they must be seen to be compiled.
-
- 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. As individual object files are built, notes are placed in
- the repository to record where templates and potential type
- arguments were seen so that the subsequent instantiation step
- knows where to find them. At link time, any needed instances are
- generated and linked in. 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; theoretically,
- this should be just as transparent, but in practice it has been
- very difficult to build multiple programs in one directory and one
- program in multiple directories using Cfront. Code written for
- this model tends to separate definitions of non-inline member
- templates into a separate file, which is magically found by the
- link preprocessor when a template needs to be instantiated.
-
- Currently, g++ implements neither automatic model. In the mean time,
- you have three options for dealing with template instantiations:
-
- 1. 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.
-
- 2. 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 use the flag
- -falt-external-templates instead; 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.
-
- 3. Explicitly instantiate all the template instances you use, and
- compile with -fno-implicit-templates. This is probably your best
- bet; it may require more knowledge of exactly which templates you
- are using, but it's less mysterious than the previous approach,
- and it doesn't require any `#pragma's or other g++-specific code.
- You can scatter the instantiations throughout your program, you
- can create one big file to do all the instantiations, or you can
- create tiny files like
-
- #include "Foo.h"
- #include "Foo.cc"
-
- template class Foo<int>;
-
- for each instance you need, and create a template instantiation
- library from those. I'm partial to the last, but your mileage may
- vary. 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.
-
- File: gcc.info, Node: C++ Signatures, Prev: Template Instantiation, Up: C++ Extensions
-
- Type Abstraction using Signatures
- =================================
-
- In GNU C++, you can use the keyword `signature' to define a
- completely abstract class interface as a datatype. You can connect this
- abstraction with actual classes using signature pointers. If you want
- to use signatures, run the GNU compiler with the `-fhandle-signatures'
- command-line option. (With this option, the compiler reserves a second
- keyword `sigof' as well, for a future extension.)
-
- Roughly, signatures are type abstractions or interfaces of classes.
- Some other languages have similar facilities. C++ signatures are
- related to ML's signatures, Haskell's type classes, definition modules
- in Modula-2, interface modules in Modula-3, abstract types in Emerald,
- type modules in Trellis/Owl, categories in Scratchpad II, and types in
- POOL-I. For a more detailed discussion of signatures, see `Signatures:
- A Language Extension for Improving Type Abstraction and Subtype
- Polymorphism in C++' by Gerald Baumgartner and Vincent F. Russo (Tech
- report CSD-TR-95-051, Dept. of Computer Sciences, Purdue University,
- August 1995, a slightly improved version appeared in
- *Software--Practice & Experience*, 25(8), pp. 863-889, August 1995).
- You can get the tech report by anonymous FTP from `ftp.cs.purdue.edu'
- in `pub/gb/Signature-design.ps.gz'.
-
- Syntactically, a signature declaration is a collection of member
- function declarations and nested type declarations. For example, this
- signature declaration defines a new abstract type `S' with member
- functions `int foo ()' and `int bar (int)':
-
- signature S
- {
- int foo ();
- int bar (int);
- };
-
- Since signature types do not include implementation definitions, you
- cannot write an instance of a signature directly. Instead, you can
- define a pointer to any class that contains the required interfaces as a
- "signature pointer". Such a class "implements" the signature type.
-
- To use a class as an implementation of `S', you must ensure that the
- class has public member functions `int foo ()' and `int bar (int)'.
- The class can have other member functions as well, public or not; as
- long as it offers what's declared in the signature, it is suitable as
- an implementation of that signature type.
-
- For example, suppose that `C' is a class that meets the requirements
- of signature `S' (`C' "conforms to" `S'). Then
-
- C obj;
- S * p = &obj;
-
- defines a signature pointer `p' and initializes it to point to an
- object of type `C'. The member function call `int i = p->foo ();'
- executes `obj.foo ()'.
-
- Abstract virtual classes provide somewhat similar facilities in
- standard C++. There are two main advantages to using signatures
- instead:
-
- 1. Subtyping becomes independent from inheritance. A class or
- signature type `T' is a subtype of a signature type `S'
- independent of any inheritance hierarchy as long as all the member
- functions declared in `S' are also found in `T'. So you can
- define a subtype hierarchy that is completely independent from any
- inheritance (implementation) hierarchy, instead of being forced to
- use types that mirror the class inheritance hierarchy.
-
- 2. Signatures allow you to work with existing class hierarchies as
- implementations of a signature type. If those class hierarchies
- are only available in compiled form, you're out of luck with
- abstract virtual classes, since an abstract virtual class cannot
- be retrofitted on top of existing class hierarchies. So you would
- be required to write interface classes as subtypes of the abstract
- virtual class.
-
- There is one more detail about signatures. A signature declaration
- can contain member function *definitions* as well as member function
- declarations. A signature member function with a full definition is
- called a *default implementation*; classes need not contain that
- particular interface in order to conform. For example, a class `C' can
- conform to the signature
-
- signature T
- {
- int f (int);
- int f0 () { return f (0); };
- };
-
- whether or not `C' implements the member function `int f0 ()'. If you
- define `C::f0', that definition takes precedence; otherwise, the
- default implementation `S::f0' applies.
-
- File: gcc.info, Node: Trouble, Next: Bugs, Prev: C++ 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.
- * External Bugs:: Problems compiling certain programs.
- * Incompatibilities:: GNU CC is incompatible with traditional C.
- * Fixed Headers:: GNU C uses corrected versions of system header files.
- This is necessary, but doesn't always work smoothly.
- * Standard Libraries:: GNU C uses the system C library, which might not be
- compliant with the ISO/ANSI C standard.
- * Disappointments:: Regrettable things we can't change, but not quite bugs.
- * C++ Misunderstandings:: Common misunderstandings with GNU C++.
- * Protoize Caveats:: Things to watch out for when using `protoize'.
- * Non-bugs:: Things we think are right, but some others disagree.
- * Warnings and Errors:: Which problems in your code get warnings,
- and which get errors.
-
- File: gcc.info, Node: Actual Bugs, Next: Installation Problems, Up: Trouble
-
- Actual Bugs We Haven't Fixed Yet
- ================================
-
- * The `fixincludes' script interacts badly with automounters; if the
- directory of system header files is automounted, it tends to be
- unmounted while `fixincludes' is running. This would seem to be a
- bug in the automounter. We don't know any good way to work around
- it.
-
- * The `fixproto' script will sometimes add prototypes for the
- `sigsetjmp' and `siglongjmp' functions that reference the
- `jmp_buf' type before that type is defined. To work around this,
- edit the offending file and place the typedef in front of the
- prototypes.
-
- * There are several obscure case of mis-using struct, union, and
- enum tags that are not detected as errors by the compiler.
-
- * When `-pedantic-errors' is specified, GNU C will incorrectly give
- an error message when a function name is specified in an expression
- involving the comma operator.
-
- * Loop unrolling doesn't work properly for certain C++ programs.
- This is a bug in the C++ front end. It sometimes emits incorrect
- debug info, and the loop unrolling code is unable to recover from
- this error.
-
-