possible compiler bug?

E

Eric

I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.
 
E

E. Robert Tisdale

Eric said:
I have a template class
that instantiates a variable of the template parameter type as follows:
[snip]

cat recursive.cc
#include <iostream>

template <class T>
struct TemplateClass {
T t;
};

struct TestClass {
int x;
static TemplateClass<TestClass> v2;
TestClass(int i = 0): x(i) { }
};

int main(int argc, char* argv[]) {
TestClass t;
std::cout << "t.x = " << t.x << std::endl;
return 0;
}
g++ -Wall -ansi -pedantic -o recursive recursive.cc
./recursive
t.x = 0
Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.
 
V

Victor Bazarov

Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

Quite possible. Try it with VC++ v 7.1.

V
 
D

David Lindauer

Victor said:
Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

Quite possible. Try it with VC++ v 7.1.

V

That definitely does compile with the borland compiler, but I am wondering what
the rules are for this since
TestClass isn't fully defined when the template is instantiated? Same thing
doesn't work without the 'static' - but doing the equivalent without a template
doesn't work at all.

David
 
E

Eric

David Lindauer said:
Victor said:
Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

Quite possible. Try it with VC++ v 7.1.

V

That definitely does compile with the borland compiler, but I am wondering what
the rules are for this since
TestClass isn't fully defined when the template is instantiated? Same thing
doesn't work without the 'static' - but doing the equivalent without a template
doesn't work at all.

David

TestClass is fully defined when TemplateClass is instantiated - static
variables are not contained in objects and thus do not influence object
size.
This is why I would expect it to compile.
 
A

Antoun Kanawati

Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.

G++ (3.4.3) takes it as well. The circular references between the
template instantiation and its surrounding class is causing some
confusion.
 
J

johnchx

David Lindauer said:
That definitely does compile with the borland compiler, but I am
wondering what the rules are for this since TestClass isn't
fully defined when the template is instantiated? Same thing
doesn't work without the 'static' - but doing the equivalent without
a template doesn't work at all.

Good question...there are a number of slightly tricky things in play
here.

First, you may or may not have noticed that TestClass::v2 isn't
defined. That means that if you write a program that tries to access
TestClass::v2, you'll get a link error. (The *compiler* won't
complain, because TestClass::v2 might be defined in some other
translation unit.)

Next, you probably want to know the point of instantiation of
TemplateClass<TestClass>. There's no explicit instantiation, so the
rules for implicit instantiation apply (14.7.1). In particular, "the
class template specialization is implicitly instantiated when the
specialization is referenced in a context that requires a
completely-defined object type or when the completeness of the class
affects the semantics of the program."

9.4.2/2 says that a static data member may be declared with an
incomplete type, so the declaration, by itself, does not cause the
instantiation of TemplateClass<TestCase>.

Of course, the *definition* of TestClass::v2 *will* require a complete
type, so that may be the point of instatiation. (It will be, unless
something else forces the instantiation first.)

Naturally, the definition of TestClass::v2 will follow the full
declaration of TestClass, so TestClass will be complete, and there
will be no difficulty instantiating TemplateClass<TestClass>, even
though it contains a non-static data member of type TestClass.

Unless I'm wrong.... :)
 
D

David Lindauer

johnchx said:
Good question...there are a number of slightly tricky things in play
here.

First, you may or may not have noticed that TestClass::v2 isn't
defined. That means that if you write a program that tries to access
TestClass::v2, you'll get a link error. (The *compiler* won't
complain, because TestClass::v2 might be defined in some other
translation unit.)

Next, you probably want to know the point of instantiation of
TemplateClass<TestClass>. There's no explicit instantiation, so the
rules for implicit instantiation apply (14.7.1). In particular, "the
class template specialization is implicitly instantiated when the
specialization is referenced in a context that requires a
completely-defined object type or when the completeness of the class
affects the semantics of the program."

9.4.2/2 says that a static data member may be declared with an
incomplete type, so the declaration, by itself, does not cause the
instantiation of TemplateClass<TestCase>.

Of course, the *definition* of TestClass::v2 *will* require a complete
type, so that may be the point of instatiation. (It will be, unless
something else forces the instantiation first.)

Naturally, the definition of TestClass::v2 will follow the full
declaration of TestClass, so TestClass will be complete, and there
will be no difficulty instantiating TemplateClass<TestClass>, even
though it contains a non-static data member of type TestClass.

Unless I'm wrong.... :)

that makes sense, thanks!

David
 
D

David Lindauer

Eric said:
David Lindauer said:
Victor said:
Eric wrote:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

Quite possible. Try it with VC++ v 7.1.

V

That definitely does compile with the borland compiler, but I am wondering what
the rules are for this since
TestClass isn't fully defined when the template is instantiated? Same thing
doesn't work without the 'static' - but doing the equivalent without a template
doesn't work at all.

David

TestClass is fully defined when TemplateClass is instantiated - static
variables are not contained in objects and thus do not influence object
size.
This is why I would expect it to compile.

Thanks!

David
 
A

Alberto Barbati

Antoun said:
Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.


G++ (3.4.3) takes it as well. The circular references between the
template instantiation and its surrounding class is causing some
confusion.

It's no confusion. The code is illegal. According to §9 para 2, "a class
is considered defined after the closing brace of its class-specifier."
Therefore at the point of declaration of v2, TestClass has not been
defined yet, so the template TemplateClass<TestClass> cannot be
instantiated because it requires T to be a complete type.

Alberto
 
E

Eric

Alberto Barbati said:
Antoun said:
Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.


G++ (3.4.3) takes it as well. The circular references between the
template instantiation and its surrounding class is causing some
confusion.

It's no confusion. The code is illegal. According to §9 para 2, "a class
is considered defined after the closing brace of its class-specifier."
Therefore at the point of declaration of v2, TestClass has not been
defined yet, so the template TemplateClass<TestClass> cannot be
instantiated because it requires T to be a complete type.

Alberto


The definition you mentioned is a little fuzzy because static
variables are not part of the definition of objects of a class. They
are global variables scoped to objects of that class.

The following code does compile under VC++, which indicates to me that
the VC++ compiler is getting confused by the template.

struct TestClass
{
int x;
static TestClass v2;
};

Eric
 
T

Thomas Mang

Alberto Barbati said:
Antoun said:
Eric said:
I have a template class that instantiates a variable of the template
parameter type as follows:

template <class T>
struct TemplateClass
{
T t;
};

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

Under Visual C++ 7 I get the following compiler error:
error C2079: 'TemplateClass<T>::t' uses undefined struct 'TestClass' with
[ T=TestClass ]

However, it compiles fine under the Borland compiler.

Is this a bug in the Visual C++ compiler?

I would appreciate any comments.


G++ (3.4.3) takes it as well. The circular references between the
template instantiation and its surrounding class is causing some
confusion.

It's no confusion. The code is illegal. According to §9 para 2, "a class
is considered defined after the closing brace of its class-specifier."
Therefore at the point of declaration of v2, TestClass has not been
defined yet, so the template TemplateClass<TestClass> cannot be
instantiated because it requires T to be a complete type.


It is true that TestClass is not defined at the line in question.
But does it matter?

Isn't the line in question only a declaration?
9.4.2/2 explicitly says:
"The declaration of a static data member in its class definition is not a
definition .....The definition for a static data member shall appear in a
namespace scope enclosing the member's class definition":


I'd consider the code legal, because at the time v2 will be defined (outside
the class body), TestClass has to be defined.


Thomas
 
A

Alberto Barbati

Thomas said:
It is true that TestClass is not defined at the line in question.
But does it matter?

Isn't the line in question only a declaration?
9.4.2/2 explicitly says:
"The declaration of a static data member in its class definition is not a
definition .....The definition for a static data member shall appear in a
namespace scope enclosing the member's class definition":


I'd consider the code legal, because at the time v2 will be defined (outside
the class body), TestClass has to be defined.

It seem that you're right and I have been mistaken. As §9.4.2/2 says
that the type doesn't need to be complete, this use of the template does
not trigger implicit instantiation of the class template, according to
§14.7.1/4. VC++ is clearly trying to instantiate the template before
it's necessary, so it's definitely a compiler bug. As a double check I
tried with Comeau Online and in fact it reports the code to be legal.

Alberto
 
A

Alberto Barbati

Thomas said:
I'd consider the code legal, because at the time v2 will be defined (outside
the class body), TestClass has to be defined.

Want to laugh? I you modify the code in this way, even VC++ happily
accepts it, confirming that the code is legal and VC++ is buggy:

template <class T>
struct TemplateClass;

struct TestClass
{
int x;
static TemplateClass<TestClass> v2;
};

template <class T>
struct TemplateClass
{
T t;
};

Funny, isn't it?

Alberto
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,244
Latest member
cryptotaxsoftware12

Latest Threads

Top