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

Bad news (was Re: Update)

It seems the patch fixed the oh-my-god-my-compiler-has-hung problem.
However, it *didn't* fix the template const/non-const problem.

This code illustrates the problem:


template<class T>
class Base
	virtual T* Foo();

class Derived2 : public Base<const char>
	const char* Foo();

class Derived1 : public Base<char>
	char* Foo();


This should be ok, right? Well, it isn't, this is the error generated:

error C2555: 'Derived1::Foo' : overriding virtual function differs from
'Base<char>::Foo' only by return type or calling convention

If the order of the definition of Derived2 and Derived1 is switched, so
that's Derived1 comes before Derived two, the error mysteriously moves
from inside Derived1 to inside Derived2:

error C2555: 'Derived2::Foo' : overriding virtual function differs from
'Base<char>::Foo' only by return type or calling convention

(of course, if this is actually the way it's supposed to work, I'm
making a fool out of myself. I can't possibly imagine that, though.)

Now, obviously, Base<char>::Foo didn't change, and neither did Derived1
or Derived2. These classes are only related in that they both derive
from the same class. Certainly, the order of declaration really
shouldn't matter.

The problem is that when Derived2 is declared first, the first occurence
of an instantion of the template class Base that the compiler encounters
is Base<const char>. This is what Derived2 then derives from.

Now, when the compiler encouters Derived1, it sees that it's supposed to
derive from Base<char>, but it doesn't think "hey, this is non-const,
the other instantiation is const, so I better make another instantion
that is non-const", no, it says "hey, this instantion kind of looks like
the other instantion I have, so that'll probably work fine; I'll just
reuse it". So, Derived1 actually gets to derive from Base<const char>,
even though Base<char> is what is actually specified. The error message
now suddenly makes sense (in a twisted MS-ish kind of way).

If this explanation is true, then we can predict that the situation
should be reversed (ie, now it's Base<char> that gets instantiated, and
not Base<const char>) when the order of Derived1 and Derived2 is
changed, and that's exactly what happens. This explanation of the
problem sounds pretty plausible to me (ie, compiler bug).

And this is for a relatively old product with the latest "service pack"
(namely VisualStudio 5.0 Service Pack 3)...

<> insert lots and lots o' MS bashing, kicking, clubbing, stabbing,
slicing up, slashing, hitting, shooting and flaming here <>

Ah well, I'll submit a bug report to MS, maybe they'll fix it. I
seriously doubt no one else has informed them of this a long time ago,
though. Maybe there is a workaround, I'll ask around.

> >Anyway, finding the *exact* cause is damn well near impossible, as I
> >have to wait 1 minute each time I try something... (the compiler locks
> Can you narrow it down to a single source file?

Not so important anymore, as the problem can be fixed by getting the
patches, though.

The problem detailed above is also in Directory.h, though.

> >Anyway, I really hope the service pack will eliminate these issues. If
> >it doesn't, it may not be worth the trouble to support MSVC++ 5.0
> I don't like the thought, but I also certainly don't like the idea of
> having to work around these bugs. Sigh.
I seem to remember there being some way of forcing instantiation of
template classes.


There is, and it actually makes the problem even more obvious:


template class Base<char>;
template class Base<const char>;

message generated:

warning C4660: template-class specialization 'Base<char>' is already

If we move them around, the *same* instantiation is made, which is
unlike my first example at the top of this post.
template class Base<const char>;
template class Base<char>;

message generated:

warning C4660: template-class specialization 'Base<char>' is already

Not only is this bug very serious, it's also inconsistent!

> Can you commit the updated VC++ project files & smaller fixes so that Peter
> can try it with VC++ 6?
Right now, I can't even compile the thing, much less build it, so
testing my settings is a bit hard...

What do you want it to be? I can certainly make it build to an .exe (if
I could build it at all). I haven't ever used DLLs though, so I haven't
a clue as to how to get MSVC to generate those.