Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > struct in struct

Reply
Thread Tools

struct in struct

 
 
Gunnar G
Guest
Posts: n/a
 
      05-31-2004
Hello.
My compiler (GCC 3.3.*) does not complain about the following:

#include <iostream>
#include <vector>
using namespace std;

struct X{
int a,b,c;
vector<X> pp;
};

int main(){
X a;
}


So there is not a problem with this self-refering struct, why?
Must not vector know the size of what it should contain?
 
Reply With Quote
 
 
 
 
Leor Zolman
Guest
Posts: n/a
 
      05-31-2004
On Mon, 31 May 2004 22:04:19 GMT, Gunnar G <(E-Mail Removed)> wrote:

>Hello.
>My compiler (GCC 3.3.*) does not complain about the following:
>
>#include <iostream>
>#include <vector>
>using namespace std;
>
>struct X{
> int a,b,c;
> vector<X> pp;
>};
>
>int main(){
> X a;
>}
>
>
>So there is not a problem with this self-refering struct, why?
>Must not vector know the size of what it should contain?


Ah, but not /yet/. At the point where pp is declared, there's nothing yet
happening where the vector "needs to know" the size of X. Go take a look at
std::vector's class definition in whatever lib (gcc, I guess) you're using,
and you'll see that it probably makes use of a pointer to X, but you won't
see any X objects themselves declared in the class definition. By the time
it needs to specialize member functions such as push_back [say, for
example, if you were to add this line to main:
a.pp.push_back(X());
] then X is a complete type and it works.
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
 
Reply With Quote
 
 
 
 
E. Robert Tisdale
Guest
Posts: n/a
 
      05-31-2004
Gunnar G wrote:
>
> My compiler (GCC 3.3.*) does not complain about the following:
>
> #include <iostream>
> #include <vector>
> using namespace std;
>
> struct X{
> int a,b,c;
> vector<X> pp;
> };
>
> int main(){
> X a;
> }
>
>
> So there is not a problem with this self-refering struct, why?
> Must not vector know the size of what it should contain?


> cat self.cc

#include <iostream>
#include <vector>

struct X{
int a,b,c;
std::vector<X> pp(1);
};

int main(int argc, char* argv[]){
X a;
return 0;
}

> g++ -Wall -ansi -pedantic -o self self.cc

self.cc:6: error: invalid data member initialization
self.cc:6: error: (use `=' to initialize static data members)
> g++ --version

g++ (GCC) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)
 
Reply With Quote
 
E. Robert Tisdale
Guest
Posts: n/a
 
      05-31-2004
Leor Zolman wrote:

> Gunnar G wrote:
>
>>My compiler (GCC 3.3.*) does not complain about the following:
>>
>>#include <iostream>
>>#include <vector>
>>using namespace std;
>>
>> struct X{
>> int a,b,c;
>> vector<X> pp;
>> };
>>
>> int main(){
>> X a;
>> return 0;
>> }
>>
>>So there is not a problem with this self-refering struct, why?
>>Must not vector know the size of what it should contain?

>
> Ah, but not /yet/. At the point where pp is declared,
> there's nothing yet happening where the vector "needs to know" the size of X.
> Go take a look at std::vector's class definition
> in whatever lib (gcc, I guess) you're using,
> and you'll see that it probably makes use of a pointer to X,
> but you won't see any X objects themselves declared in the class definition.


Are you saying that this behavior is implementation dependent?

> By the time it needs to specialize member functions such as push_back
> [say, for example, if you were to add this line to main:
> a.pp.push_back(X());
> ] then X is a complete type and it works.

 
Reply With Quote
 
Leor Zolman
Guest
Posts: n/a
 
      06-01-2004
On Mon, 31 May 2004 15:33:42 -0700, "E. Robert Tisdale"
<(E-Mail Removed)> wrote:

>Gunnar G wrote:
>>
>> My compiler (GCC 3.3.*) does not complain about the following:
>>
>> #include <iostream>
>> #include <vector>
>> using namespace std;
>>
>> struct X{
>> int a,b,c;
>> vector<X> pp;
>> };
>>
>> int main(){
>> X a;
>> }
>>
>>
>> So there is not a problem with this self-refering struct, why?
>> Must not vector know the size of what it should contain?

>
> > cat self.cc

> #include <iostream>
> #include <vector>
>
> struct X{
> int a,b,c;
> std::vector<X> pp(1);


Um, the OP's original example somehow seems to have grown a "(1)" by the
time it reached your computer. I can't explain why. Using the original
example,

d:\src\learn>g++ -Wall -ansi -pedantic x.cpp
d:\src\learn>

-leor

> };
>
> int main(int argc, char* argv[]){
> X a;
> return 0;
> }
>
> > g++ -Wall -ansi -pedantic -o self self.cc

> self.cc:6: error: invalid data member initialization
> self.cc:6: error: (use `=' to initialize static data members)
> > g++ --version

> g++ (GCC) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
 
Reply With Quote
 
Leor Zolman
Guest
Posts: n/a
 
      06-01-2004
On Mon, 31 May 2004 15:41:10 -0700, "E. Robert Tisdale"
<(E-Mail Removed)> wrote:

>Leor Zolman wrote:
>
>> Gunnar G wrote:
>>
>>>My compiler (GCC 3.3.*) does not complain about the following:
>>>
>>>#include <iostream>
>>>#include <vector>
>>>using namespace std;
>>>
>>> struct X{
>>> int a,b,c;
>>> vector<X> pp;
>>> };
>>>
>>> int main(){
>>> X a;
>>> return 0;
>>> }
>>>
>>>So there is not a problem with this self-refering struct, why?
>>>Must not vector know the size of what it should contain?

>>
>> Ah, but not /yet/. At the point where pp is declared,
>> there's nothing yet happening where the vector "needs to know" the size of X.
>> Go take a look at std::vector's class definition
>> in whatever lib (gcc, I guess) you're using,
>> and you'll see that it probably makes use of a pointer to X,
>> but you won't see any X objects themselves declared in the class definition.

>
>Are you saying that this behavior is implementation dependent?


No I'm not; nor am I saying it isn't. I don't truly know. I was suggesting
how it could be possible, on the OP's platform, for that declaration of pp
to work with the incomplete (at that point) type X.
-leor

>
>> By the time it needs to specialize member functions such as push_back
>> [say, for example, if you were to add this line to main:
>> a.pp.push_back(X());
>> ] then X is a complete type and it works.


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
 
Reply With Quote
 
E. Robert Tisdale
Guest
Posts: n/a
 
      06-01-2004
Leor Zolman wrote:

> E. Robert Tisdale wrote:
>
>>Gunnar G wrote:
>>
>>>My compiler (GCC 3.3.*) does not complain about the following:
>>>
>>>#include <iostream>
>>>#include <vector>
>>>using namespace std;
>>>
>>>struct X{
>>> int a,b,c;
>>> vector<X> pp;
>>> };
>>>
>>>int main(){
>>> X a;
>>> }
>>>
>>>
>>>So there is not a problem with this self-refering struct, why?
>>>Must not vector know the size of what it should contain?

>>
>> > cat self.cc

>> #include <iostream>
>> #include <vector>
>>
>> struct X{
>> int a,b,c;
>> std::vector<X> pp(1);

>
>
> Um, the OP's original example somehow seems to have grown a "(1)" by the
> time it reached your computer. I can't explain why. Using the original
> example,
>
> d:\src\learn>g++ -Wall -ansi -pedantic x.cpp
> d:\src\learn>


Which, I believe,
is what Gunnar G was reporting for an *empty* container.

> cat self.cc

#include <iostream>

template <typename T>
struct myVector {
T a[1];
};

struct X{
int a,b,c;
myVector<X> pp;
};

int main(int argc, char* argv[]){
X a;
return 0;
}

> g++ -Wall -ansi -pedantic -o self self.cc

self.cc: In instantiation of `myVector<X>':
self.cc:10: instantiated from here
self.cc:5: error: `myVector<T>::a' has incomplete type
self.cc:8: error: forward declaration of `struct X'
self.cc: In function `int main(int, char**)':
self.cc:14: warning: unused variable `X a'

is probably the case that Gunnar G was concerned about.
 
Reply With Quote
 
Denis Remezov
Guest
Posts: n/a
 
      06-01-2004
Gunnar G wrote:
>
> > Which, I believe,
> > is what Gunnar G was reporting for an *empty* container.
> >
> > > cat self.cc

> > #include <iostream>
> >
> > template <typename T>
> > struct myVector {
> > T a[1];
> > };
> >
> > struct X{
> > int a,b,c;
> > myVector<X> pp;
> > };
> >
> > int main(int argc, char* argv[]){
> > X a;
> > return 0;
> > }
> >
> > > g++ -Wall -ansi -pedantic -o self self.cc

> > self.cc: In instantiation of `myVector<X>':
> > self.cc:10: instantiated from here
> > self.cc:5: error: `myVector<T>::a' has incomplete type
> > self.cc:8: error: forward declaration of `struct X'
> > self.cc: In function `int main(int, char**)':
> > self.cc:14: warning: unused variable `X a'
> >
> > is probably the case that Gunnar G was concerned about.

>
> So, you get an error here since you are declaring the array T a[1], and that
> implies that something (the compiler?) would have to know the size of the
> "T" in order to allocate memory? But with a STL-vector , it uses (perhaps
> pointers) so it would not have to know the size, or the size is easy to
> find, since it's just an sizeof(int)+sizeof(X-pointer)+overhead ?


I think there is a way to break your original example by requiring the
template parameter to be a complete type for the purpose of vector's member
specification. Imagine an implementation like this:

template <typename T, class Allocator = allocator <T> >
class vector {
enum {
element_size = sizeof(T)
};

//...
};

I haven't decided why anyone would want to do that, but wouldn't it
still be a conforming implementation?

Denis
 
Reply With Quote
 
Leor Zolman
Guest
Posts: n/a
 
      06-01-2004
On Mon, 31 May 2004 19:00:06 -0700, "E. Robert Tisdale"
<(E-Mail Removed)> wrote:

>Leor Zolman wrote:
>
>> E. Robert Tisdale wrote:
>>
>>>Gunnar G wrote:
>>>
>>>>My compiler (GCC 3.3.*) does not complain about the following:
>>>>
>>>>#include <iostream>
>>>>#include <vector>
>>>>using namespace std;
>>>>
>>>>struct X{
>>>> int a,b,c;
>>>> vector<X> pp;
>>>> };
>>>>
>>>>int main(){
>>>> X a;
>>>> }
>>>>
>>>>
>>>>So there is not a problem with this self-refering struct, why?
>>>>Must not vector know the size of what it should contain?
>>>
>>> > cat self.cc
>>> #include <iostream>
>>> #include <vector>
>>>
>>> struct X{
>>> int a,b,c;
>>> std::vector<X> pp(1);

>>
>>
>> Um, the OP's original example somehow seems to have grown a "(1)" by the
>> time it reached your computer. I can't explain why. Using the original
>> example,
>>
>> d:\src\learn>g++ -Wall -ansi -pedantic x.cpp
>> d:\src\learn>

>
>Which, I believe,
>is what Gunnar G was reporting for an *empty* container.


Sorry, I have no idea what you're talking about. He was reporting that
he drew no errors, and asking how that could be--a perfectly
reasonable question, IMO. I would probably have guessed, if shown his
code, without being told it compiles, that it should have drawn an
error. But it does not; so, as per Mr. Holmes, "When you have
eliminated the impossible..."

>
> > cat self.cc

> #include <iostream>
>
> template <typename T>
> struct myVector {
> T a[1];
> };
>
> struct X{
> int a,b,c;
> myVector<X> pp;
> };
>
> int main(int argc, char* argv[]){
> X a;
> return 0;
> }
>
> > g++ -Wall -ansi -pedantic -o self self.cc

> self.cc: In instantiation of `myVector<X>':
> self.cc:10: instantiated from here
> self.cc:5: error: `myVector<T>::a' has incomplete type
> self.cc:8: error: forward declaration of `struct X'
> self.cc: In function `int main(int, char**)':
> self.cc:14: warning: unused variable `X a'
>
>is probably the case that Gunnar G was concerned about.


Why isn't the case he actually showed us the one he was most likely to
actually be concerned about? Why would he have taken the trouble to
obfuscate what he was /really/ wanting to know about, by conjuring up
such an example that does not draw an error?
-leor


 
Reply With Quote
 
Gunnar G
Guest
Posts: n/a
 
      06-01-2004
> Which, I believe,
> is what Gunnar G was reporting for an *empty* container.
>
> > cat self.cc

> #include <iostream>
>
> template <typename T>
> struct myVector {
> T a[1];
> };
>
> struct X{
> int a,b,c;
> myVector<X> pp;
> };
>
> int main(int argc, char* argv[]){
> X a;
> return 0;
> }
>
> > g++ -Wall -ansi -pedantic -o self self.cc

> self.cc: In instantiation of `myVector<X>':
> self.cc:10: instantiated from here
> self.cc:5: error: `myVector<T>::a' has incomplete type
> self.cc:8: error: forward declaration of `struct X'
> self.cc: In function `int main(int, char**)':
> self.cc:14: warning: unused variable `X a'
>
> is probably the case that Gunnar G was concerned about.


So, you get an error here since you are declaring the array T a[1], and that
implies that something (the compiler?) would have to know the size of the
"T" in order to allocate memory? But with a STL-vector , it uses (perhaps
pointers) so it would not have to know the size, or the size is easy to
find, since it's just an sizeof(int)+sizeof(X-pointer)+overhead ?

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Typedef A references struct B which references struct A which... DanielEKFA C++ 8 05-16-2005 10:26 AM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM
implementing a templated struct within a templated struct RA Scheltema C++ 3 01-06-2004 11:25 AM
To coerce or not...? struct sockaddr vs struct sockaddr_in James Harris C Programming 4 10-09-2003 10:06 PM



Advertisments