Here we go: I noticed that if I nest a structure inside another one,
the wrong constructor will be called.. the one from a different class!!
Here is some test code:
---
struct One {
int o;
One() {
printf("Into the constructor of One which is inherited by ");
};
};
struct Two : One {
int t;
Two() {
printf("Two\n");
};
};
struct Zwei : One {
int z;
Zwei() {
printf("Zwei\n");
};
};
struct Dos : One {
int d;
Dos() {
printf("Dos\n");
};
};
struct MyFinalStruct_this_acts_bug_free {
Two MyObject1;
Zwei MyObject2;
Dos MyObject3;
} ;
struct MyFinalStruct_this_produces_the_bug {
struct {
Two MyObject1;
} A;
struct {
Zwei MyObject2;
} B;
struct {
Dos MyObject3;
} C;
} ;
int main() {
printf("...testing the first structure:\n");
MyFinalStruct_this_acts_bug_free Test1;
printf("...testing the second structure:\n");
MyFinalStruct_this_produces_the_bug Test2;
// --
return(0);
}
---
The above program produces this output, at least on my compiler:
---
...testing the first structure:
Into the constructor of One which is inherited by Two
Into the constructor of One which is inherited by Zwei
Into the constructor of One which is inherited by Dos
...testing the second structure:
Into the constructor of One which is inherited by Two
Into the constructor of One which is inherited by Two
Into the constructor of One which is inherited by Two
---
Is this normal? The first output is what I would definitely expect
also from the other structure!
Thanks,
Fabio
[snip code]
> Is this normal? The first output is what I would definitely expect
> also from the other structure!
It appears to be a bug. After adding the needed
"#include <cstdio>
using namespace std"
, GCC produces the following output:
[ccox-macbook:~] ccox% g++ test.cpp && ./a.out
...testing the first structure:
Into the constructor of One which is inherited by Two
Into the constructor of One which is inherited by Zwei
Into the constructor of One which is inherited by Dos
...testing the second structure:
Into the constructor of One which is inherited by Two
Into the constructor of One which is inherited by Zwei
Into the constructor of One which is inherited by Dos
--
Clark S. Cox III
clar...@gmail.com
[code]
FWIW, GCC 4.1 disagrees with MSC14 in that aspect, it produces the same
output for both cases as one would expect.
Uli
playground.obj : fatal error LNK1179: invalid or corrupt file:
duplicate COMDAT
'??0<unnamed-tag>@MyFinalStruct_this_produces_the_bug@@QAE@XZ'
This is also VC++ 2005. Standard edition. This is a copy paste of the
OP code with namespace std and some includes.
Yeah, obviously buggy. I did a google search for this error and came
up with a number of things, all unrelated to each other and none fit
this situation.
Fun stuff.
I get the same linking error as Noah Roberts. Actually,
anonymous structures are not allowed by the C++ Standard,
however MSVC++ permits them as MS extension. When I added
names to MyFinalStruct_this_produces_the_bug nested structs
everything compiled and ran properly:
struct MyFinalStruct_this_produces_the_bug {
struct tagA {
Two MyObject1;
} A;
struct tagB {
Zwei MyObject2;
} B;
struct tagC {
Dos MyObject3;
} C;
} ;
Aren't they?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
>* Alex Blekhman:
>> anonymous structures are not allowed by the C++ Standard,
>Aren't they?
This would seem a good thing to clear up. ;) Seems you
need them for C back-compatibility.
Steve
Hm.. It appears that you're right. I confused OP example
with declaration of unnamed anonymous struct:
// compiles with MS extensions enabled, fails with /Za
switch
struct A
{
struct
{
int i;
};
};
> I get the same linking error as Noah Roberts. Actually,
> anonymous structures are not allowed by the C++ Standard,
There is no such thing as an anonymous struct (in the sense
of an anonymous union) in C++. These are not anonymous structs
in that sense, they are just unnamed ones. Since the struct
does define a variable, it is not anonymous and legal in this
use.
>I get this:
>
>playground.obj : fatal error LNK1179: invalid or corrupt file:
>duplicate COMDAT
>'??0<unnamed-tag>@MyFinalStruct_this_produces_the_bug@@QAE@XZ'
>
>This is also VC++ 2005. Standard edition. This is a copy paste of the
>OP code with namespace std and some includes.
>
>Yeah, obviously buggy.
I also get the linker error, with both VC++ 2003 and VC++ 2005, but if you
look at the generated code with /Fc, you can see that it generates three
separate constructors, but gives them all the exact same name
(??0<unnamed-tag>@MyFinalStruct_this_produces_the_bug@@QAE@X). The
MyFinalStruct_this_produces_the_bug constructor then calls this name three
times.
--
- Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.