[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug c++/14502] [3.3 Regression] g++ compile fails "no matching function

From: bangerth at dealii dot org
Subject: [Bug c++/14502] [3.3 Regression] g++ compile fails "no matching function" using forward declaration of class involving inheritance
Date: 10 Mar 2004 22:42:10 -0000

------- Additional Comments From bangerth at dealii dot org  2004-03-10 22:42 
This is actually an interesting problem, and I'm not at all convinced 
that we do the right thing. Here's a redux: 
template <class T> struct B {}; 
template <class T> void bar () 
{ B<T> *p = (T*)0; } 
struct D; 
int foo()  { bar<D>(); }; 
struct D : public B<D> {}; 
int i = foo(); 
Now, 3.2.3 compiles this as do 3.4 and mainline, but 3.3.4 doesn't. My 
grapples with this are: when we see foo(), we realize that this is not 
a template, so we should expand its body. At this time, D is only 
forward declared, so when we instantiate bar<D> we realize that we are 
asked to convert a D* to a B<D>* in the assignment. 3.3.x tells us 
g/x> /home/bangerth/bin/gcc-3.3*/bin/c++ -c In function `void bar() [with T = D]':   instantiated from here error: cannot convert `D*' to `B<D>*' in initialization 
I believe this is a sensible error message, since at the time of instantiation 
of bar<D>, we are unaware of the fact that D is actually derived from B<D> 
and that therefore a D* _can_ be converted into a B<D>*. 
So apparently the confusion all comes from the fact that 3.3 tries to 
expand the body of foo() when it sees the function definition, while all 
other versions of the compiler only try to do so when this function is 
actually used or at the end of the compilation unit. This is supported by 
the fact that if we remove the last definition of D and of the variable i 
from the file, then suddenly also the other compilers get into trouble. 
So, in my view 3.3 is actually the only version that gets it right, i.e. 
expands the body of the function at the point of its definition; we probably 
all agree that this is the sensible thing to do for non-templates. All other 
versions defer expansion of the body of bar() until the end of the translation 
unit, at which point the definition of D is already known. In other words, 
we would have an accepts-invalid in 3.2.3, 3.4 and mainline (and thus a 
regression), not a rejects-valid in 3.3. 
Does this all sound sensible? 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]