CG bug in VC7.1?

H

Hendrik Schober

Hi,

consider this:

#include <iostream>

struct Base {
Base() {std::cout << "Base\n";}
Base(Base&) {std::cout << "Base(Base&)\n";}
};

template< typename T >
struct TBase : Base {
TBase() : Base() {};
TBase(Base& obj) : Base(obj) {std::cout << "TBase(Base&)\n";}
};

struct Derived : TBase<int> {
Derived() : TBase<int>() {std::cout << "Derived()\n";}
Derived(Derived& obj) : TBase<int>(obj) {std::cout << "Derived(Derived&)\n";}
};


int main()
{
Derived d1;
Derived d2(d1);
return 0;
}

(Of course, this doesn' make sense. The real code
is a lot more complicated.)
Using VC7.1 this outputs

Base
TBase()
Derived()
Base(Base&)
Derived(Derived&)

whereas I would have expected

Base
TBase()
Derived()
Base(Base&)
TBase(Base&)
Derived(Derived&)

Am I missing something or is the compiler wrong?

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett
 
C

Carl Daniel [VC++ MVP]

Hendrik said:
Hi,
[snipped]

Am I missing something or is the compiler wrong?

I'd say the compiler's wrong. Does using const references in the
constructor argument lists make any difference? Have you tried VC++ 2005?
Do optimizationg settings make any difference?

-cd
 
I

Ioannis Vranos

Hendrik said:
(Of course, this doesn' make sense. The real code
is a lot more complicated.)
Using VC7.1 this outputs

Base
TBase()
Derived()
Base(Base&)
Derived(Derived&)

whereas I would have expected

Base
TBase()
Derived()
Base(Base&)
TBase(Base&)
Derived(Derived&)



Actually it outputs


C:\c>temp
Base
Derived()
Base(Base&)
Derived(Derived&)

C:\c>





At first I want to note that you use some unneeded explicit calls to
base constructors.


I will mark what is called with numbers for the first object, just
follow the numbers from the largest to the smaller:


#include <iostream>

struct Base {
==>1 Base() {std::cout << "Base\n";}
Base(Base&) {std::cout << "Base(Base&)\n";}
};

template< typename T >
struct TBase : Base {
==>2 TBase() : Base() {};
TBase(Base& obj) : Base(obj) {std::cout << "TBase(Base&)\n";}
};

struct Derived : TBase<int> {
==>3 Derived() : TBase<int>() {std::cout <<
"Derived()\n";}

Derived(Derived& obj) : TBase<int>(obj) {std::cout <<
"Derived(Derived&)\n";}
};


int main()
{
Derived d1;
}
 
T

Tom Widmer

Hendrik said:
Hi,

consider this:

#include <iostream>

struct Base {
Base() {std::cout << "Base\n";}
Base(Base&) {std::cout << "Base(Base&)\n";}
};

template< typename T >
struct TBase : Base {
TBase() : Base() {};
TBase(Base& obj) : Base(obj) {std::cout << "TBase(Base&)\n";}
};

struct Derived : TBase<int> {
Derived() : TBase<int>() {std::cout << "Derived()\n";}
Derived(Derived& obj) : TBase<int>(obj) {std::cout << "Derived(Derived&)\n";}

TBase<int>(obj) calls TBase<int>(TBase&) (the implicitly defined copy
constructor), not TBase<int>(Base&) as you are expecting -
Derived->TBase said:
};


int main()
{
Derived d1;
Derived d2(d1);
return 0;
}

(Of course, this doesn' make sense. The real code
is a lot more complicated.)
Using VC7.1 this outputs

Base
TBase()
Derived()
Base(Base&)
Derived(Derived&)

whereas I would have expected

Base
TBase()
Derived()
Base(Base&)
TBase(Base&)
Derived(Derived&)

Am I missing something or is the compiler wrong?

I think it's right.

Tom
 
H

Hendrik Schober

Ioannis Vranos said:
[...]
Using VC7.1 this outputs

Base
TBase()
Derived()
Base(Base&)
Derived(Derived&)

[...]

Actually it outputs


C:\c>temp
Base
Derived()
Base(Base&)
Derived(Derived&)

You're right. Sorry for this stupid
copy'n'paste error.
At first I want to note that you use some unneeded explicit calls to
base constructors.

This was code to show the problem.
The real code is much more messy. I
just reduced it to what I posted and
didn't go through looking for this.


Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett
 
H

Hendrik Schober

Tom Widmer said:
TBase<int>(obj) calls TBase<int>(TBase&) (the implicitly defined copy
constructor), not TBase<int>(Base&) as you are expecting -
Derived->TBase<int> is a better conversion than Derived->Base.

You're right!
Inserting 'TBase::TBase(TBase& obj)' shows that
this indeed is called.
I didn't know that a ctor taking a non-const
reference would be considered a copy ctor --
let alone that the compiler would generate
such a beast when it is needed! But Comeau
accepts it, so it really seems right. (Not
that I would questions your judgements! said:
[...]
Am I missing something or is the compiler wrong?

I think it's right.
Thanks!

Tom


Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett
 
H

Hendrik Schober

Carl Daniel said:
Hendrik said:
Hi,
[snipped]

Am I missing something or is the compiler wrong?

[...] Does using const references in the
constructor argument lists make any difference? [...]

I think it did. However, a non-const
ref is needed there.
(But I think Tom explained what was
wrong with the code -- or rather with
my expectations of what it should do!)


Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett
 

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

Top