This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [G++] templates not instantiated early enough
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: Chris Lattner <sabre at nondot dot org>
- Cc: gcc at gcc dot gnu dot org
- Date: 04 Jun 2004 10:20:50 +0200
- Subject: Re: [G++] templates not instantiated early enough
- Organization: Integrable Solutions
- References: <Pine.LNX.4.44.0406040250540.32435-100000@nondot.org>
Chris Lattner <sabre@nondot.org> writes:
[...]
| > | In particular, the prototype for foo doesn't
| > | get emitted to the backend until foo is referenced in "bar".
| >
| > I don't understand this. When foo is declared, it gets assigned a
| > type, which is FUNCTION_TYPE (void, some_template<int>).
|
| Yes, of course you're right. The problem is that the function prototype
| is being mark_used and sent to the backend. At this point the template is
| not instantiated yet, so the backend can't look into the structure
| argument to see what it contains. Andrew pointed out an example of how
| this can actually result in an erroneous program not being flagged as
| such.
Such as your program :-) -- you used foo but you did not provide a
definition for it. Note, that if you replace the template with an
ordinary function, you get the same behaviour (the program is still
ill-formed).
struct fu;
void foo(fu); // OK
void bar() {
foo; // use of foo, needs definition
}
| > | This happens
| > | when the parser sees the reference to foo, and decides that it really
| > | is referring to the foo function in finish_id_expression.
| > |
| > | The problem is that, in this testcase (which is reduced from a
| > | non-pointless larger testcase), the some_template is never instantiated
| > | with an int type.
| >
| > It does not need to. Its completeness is not required. It is only
| > referenced in a context of parameter-type-list, in a declaration
| > of foo and no call if made to that function.
|
| That's fine, and I understand how it is valuable to avoid instantiation
| tons of templates that aren't used.
It is not question of being "valuable". The issue is very simple.
Did your program fragment needed some_template<int> to be complete?
The answer is no. There is not but.
| However, the foo function is
| referenced in the program, despite the fact that it is not called.
So, you need to define the function foo. Now, it you *define* the
function foo, then because some_template<int> is used as a parameter
type, it needs to be instantiated. But you were not doing that in the
program fragment you showed. Therefore the error, if any, was in your
program.
| Because it is being referenced, I believe the template ought to be
| instantiated (even if it's not a call).
No.
| > | This causes problems for my backend, which needs to
| > | look at the types for arguments for foo.
| >
| > If your backend unconditionally assumes that any type referenced in a
| > function declaration ought to be a complete type, then it contains a bug.
|
| It's not that it unconditionally assumes it: that would be easy to fix.
| The problem is that it needs to know the elements and layout information
| about structures passed by values when it emits the prototypes to the
| backend.
Then define the function foo!
-- Gaby