468,110 Members | 1,583 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,110 developers. It's quick & easy.

possible compiler bug?

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.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #1
13 1762
Eric wrote:
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.

Jul 22 '05 #2
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
Jul 22 '05 #3


Victor Bazarov wrote:
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
Jul 22 '05 #4

"David Lindauer" <ca*****@bluegrass.net> wrote in message
news:41***************@bluegrass.net...


Victor Bazarov wrote:
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.
Jul 22 '05 #5
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?

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.
--
A. Kanawati
NO*************@comcast.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jul 22 '05 #6
David Lindauer <ca*****@bluegrass.net> wrote i
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;
};

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.... :-)
Jul 22 '05 #7


johnchx wrote:
David Lindauer <ca*****@bluegrass.net> wrote i
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;
> };
>

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.... :-)


that makes sense, thanks!

David
Jul 22 '05 #8


Eric wrote:
"David Lindauer" <ca*****@bluegrass.net> wrote in message
news:41***************@bluegrass.net...


Victor Bazarov wrote:
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
Jul 22 '05 #9
Antoun Kanawati wrote:
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?

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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #10
Alberto Barbati <Al************@libero.it> wrote in message news:<nD********************@twister2.libero.it>.. .
Antoun Kanawati wrote:
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?

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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jul 22 '05 #11

"Alberto Barbati" <Al************@libero.it> schrieb im Newsbeitrag
news:nD********************@twister2.libero.it...
Antoun Kanawati wrote:
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?

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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #12
Thomas Mang wrote:
"Alberto Barbati" <Al************@libero.it> schrieb im Newsbeitrag
news:nD********************@twister2.libero.it...
>
> 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.


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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #13
Thomas Mang wrote:

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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Rob Williscroft | last post: by
9 posts views Thread by Vinodh Kumar P | last post: by
3 posts views Thread by Chris Calzaretta | last post: by
24 posts views Thread by Arne Demmers | last post: by
71 posts views Thread by Jack | last post: by
1 post views Thread by Solo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.