CG bug in VC7.1?

  • Thread starter Thread starter Hendrik Schober
  • Start date Start date
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
 
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
 
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;
}
 
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
 
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
 
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
 
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
 
Back
Top