Re: Is it me or is it gcc?
Hello,
Boltar wrote:
On Sep 12, 3:25 pm, blargg....@gishpuppy.com (blargg) wrote:
How so? In both cases below the compiler doesn't know anything about
the type derived from, since Foo could have specializations:
template<typename T> class U : public T;
template<typename T> class Foo { ... };
template<typename T> class U : public Foo<T>;
It doesn't in my example. For heavens sake , is it too much to ask a
compiler to know when specialisation is in use and when it isn't in
the same module for the same class?
A compiler cannot sensibly work in a way that it makes assumptions which
might be broken later on. If it took the wibble in your example as you
like it, somebody else could change your example by adding a
specialization for the base class and bring the compiler into trouble.
Older releases of gcc basically did some kind of textual insertion with
the macros at instantiation time, so all lookups happened at the point
that is now the second phase of lookup. The problem with that is, that
you basically could not have fixed meanings for names when the code is
parsed first time by the compiler, fixed in the sense that no later
specialization can change it. The first phase of name lookup for
templates ensures that this is possible.
I'd rather a compiler which followed well-defined rules rather than
vague things like "obvious", which differ from one person to the
next. For one, the compiler sees a lot more than the human does, in
terms of all the details.
Rubbish. These rules make it virtually impossible to use inheritence
with templates. Which rather defeats the point of using C++. As I said
earlier , I might as well use C. I'm pretty sure the compiler writers
have understood this which is why 4.2.1 doesn't error and just
compiles the code.
Then gcc 4.3 has reverted 4.2.1 again. 4.2.2 seems to have serious
problems with your example modified a little, it compiles the
following:
template <typename T>
class n1
{
public:
int wibble;
};
template<typename T>
class n2: public n1<T>
{
public:
void test()
{
this->wibble = 1;
//::wibble = 1; global variable
// wibble = 1; //this->wibble or ::wibble ?
// max(3,4)
/* this->max or std::max (with using namespace std) */
}
};
template<>
class n1<int>
{
public:
int wobble;
// int max(int,int);
};
int main()
{
n2<int> n;
n.test();
return 0;
}
Imagine you have something named wibble in the same namespace as n2. How
would you distinguish between that wibble and the wibble of class
template n1? Especially how would you do that at the point you are
parsing the body of your method test(), without making speculations? If
the compiler sees the wibble alone and took it as an argument-dependent
name, then suddenly all non-related names used within templates would
have to be fully qualified to distinguish them, think about the
max-example above. That would be quite a lot more work in non-trivial
templates than having to add this-> to make something
argument-dependent.
Bernd Strieder