Go forward to Glossary.
Go backward to Routines.
Go up to Top.
Implementation Specifics
========================
* Explicit Initialization
The global list `current_member_init_list' contains the list of
mem-initializers specified in a constructor declaration. For
example:
foo::foo() : a(1), b(2) {}
will initialize `a' with 1 and `b' with 2. `expand_member_init'
places each initialization (a with 1) on the global list. Then,
when the fndecl is being processed, `emit_base_init' runs down the
list, initializing them. It used to be the case that g++ first
ran down `current_member_init_list', then ran down the list of
members initializing the ones that weren't explicitly initialized.
Things were rewritten to perform the initializations in order of
declaration in the class. So, for the above example, `a' and `b'
will be initialized in the order that they were declared:
class foo { public: int b; int a; foo (); };
Thus, `b' will be initialized with 2 first, then `a' will be
initialized with 1, regardless of how they're listed in the
mem-initializer.
* Argument Matching
In early 1993, the argument matching scheme in GNU C++ changed
significantly. The original code was completely replaced with a
new method that will, hopefully, be easier to understand and make
fixing specific cases much easier.
The `-fansi-overloading' option is used to enable the new code; at
some point in the future, it will become the default behavior of
the compiler.
The file `cp-call.c' contains all of the new work, in the functions
`rank_for_overload', `compute_harshness',
`compute_conversion_costs', and `ideal_candidate'.
Instead of using obscure numerical values, the quality of an
argument match is now represented by clear, individual codes. The
new data structure `struct harshness' (it used to be an `unsigned'
number) contains:
a. the `code' field, to signify what was involved in matching two
arguments;
b. the `distance' field, used in situations where inheritance
decides which function should be called (one is "closer" than
another);
c. and the `int_penalty' field, used by some codes as a
tie-breaker.
The `code' field is a number with a given bit set for each type of
code, OR'd together. The new codes are:
* `EVIL_CODE' The argument was not a permissible match.
* `CONST_CODE' Currently, this is only used by
`compute_conversion_costs', to distinguish when a non-`const'
member function is called from a `const' member function.
* `ELLIPSIS_CODE' A match against an ellipsis `...' is
considered worse than all others.
* `USER_CODE' Used for a match involving a user-defined
conversion.
* `STD_CODE' A match involving a standard conversion.
* `PROMO_CODE' A match involving an integral promotion. For
these, the `int_penalty' field is used to handle the ARM's
rule (XXX cite) that a smaller `unsigned' type should promote
to a `int', not to an `unsigned int'.
* `QUAL_CODE' Used to mark use of qualifiers like `const' and
`volatile'.
* `TRIVIAL_CODE' Used for trivial conversions. The
`int_penalty' field is used by `convert_harshness' to
communicate further penalty information back to
`build_overload_call_real' when deciding which function should
be call.
The functions `convert_to_aggr' and `build_method_call' use
`compute_conversion_costs' to rate each argument's suitability for
a given candidate function (that's how we get the list of
candidates for `ideal_candidate').