Topic: class Foo; vector <Foo*> v;


Author: Enno Rehling <enno@uni-paderborn.de>
Date: 1997/03/05
Raw View
> Is it legal to say:
>
> class Foo;
> vector <Foo*> v;
>
> My understanding of STL is that this should be legal.  When v is
> destroyed, any elements in it (which are pointers to Foo) are destroyed.
> Destroying a built-in C pointer doesn't also destroy what the pointer
> points at.  Yet my compiler (MSVC 4.2) complains; as near as I can tell,
> it IS attempting to destroy the referents of the contained pointers, and
> hence it complains since it has not seen a definition of Foo (and hence
> Foo's destructor).

1st of all, yes, it's legal. Doesn't mean it woks, though. I had a similar
problem with g++ 2.7.2 recently, and VC 4.0 reports the same problem you
have. The thing is, the compilers should only instantiate the function when
they are required. However, not all compilers hold true to that, and
instantiate the function prior to its being used. In this case, I'm not
really sure, though. Could anyone claryfi when a compiler should
instantiate the destructor of vector<Foo*> v, if v is global and never
used? after creating main() and everything else ?

Enno.
--

Enno Rehling  Kilianstra_e 129a  33098 Paderborn  Germany
rehling@usa.net  http://hrz.uni-paderborn.de/~q09960/public/
Tel/Fax: Int+ 49 (0) 5251-760796


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]






Author: John Lilley <jlilley@empathy.com>
Date: 1997/03/06
Raw View
Marcelo Cantos wrote:
>
> Russ Williams wrote:
> > class Foo;
> > vector <Foo*> v;
> > ...Yet my compiler (MSVC 4.2) complains...
>
> This is probably a bug in your compiler.

Righto.  I've hit this one as well.  As a further clarification, the
problem comes down to the fact that in templates, the contained thing is
often destructed "in place" by something like:

     p->~T();

Now, if T is Foo*, and Foo is incomplete, then MSVC++ 4.2 does not like
p->~T() because it thinks that in order to destruct the pointer (a
no-op) it must know the type of the thing pointed to.  Compiler boo-boo.

john lilley
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: John Lilley <jlilley@empathy.com>
Date: 1997/03/06
Raw View
Russ Williams wrote:
>
> Is it legal to say:
>
> class Foo;
> vector <Foo*> v;
>
> My understanding of STL is that this should be legal.  When v is
> destroyed, any elements in it (which are pointers to Foo) are destroyed.
> Destroying a built-in C pointer doesn't also destroy what the pointer
> points at.  Yet my compiler (MSVC 4.2) complains; as near as I can tell,
> it IS attempting to destroy the referents of the contained pointers, and
> hence it complains since it has not seen a definition of Foo (and hence
> Foo's destructor).

MSVC++ isn't atempting to destroy the pointed-to objects.  The syntax it
uses inside the template is something like:

p->~T();

Where T is the parametized type (Foo* in your example).  This just
destroys the pointer, not the pointed-to object.  The compiler error is
that it doesn't understand that destroying the pointer (a no-op) should
be allowed even when the referent is not complete.

john lilley
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]






Author: Michael R Cook <mcook@cognex.com>
Date: 1997/03/06
Raw View
>>>>> "JL" == John Lilley <jlilley@empathy.com> writes:

 JL> Now, if T is Foo*, and Foo is incomplete, then MSVC++ 4.2 does not
like
 p-> ~T() because it thinks that in order to destruct the pointer (a
 JL> no-op) it must know the type of the thing pointed to.  Compiler
boo-boo.

That strikes me as proper behavior.  After all, the destructor might be
private.

--
 Michael Cook <mcook@cognex.com>        <http://ftp.cognex.com/~mcook/>
 Telephone: +1 508 650 3251                        Fax: +1 508 650 3336
 Cognex Corporation, One Vision Drive, Natick, Massachusetts 01760-2059

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1997/03/07
Raw View
Michael R Cook <mcook@cognex.com> writes:

> >>>>> "JL" == John Lilley <jlilley@empathy.com> writes:
>
>  JL> Now, if T is Foo*, and Foo is incomplete, then MSVC++ 4.2 does not
> like
>  p-> ~T() because it thinks that in order to destruct the pointer (a
>  JL> no-op) it must know the type of the thing pointed to.  Compiler
> boo-boo.
>
> That strikes me as proper behavior.  After all, the destructor might be
> private.

It isn't, though.  What's relevant is the destructor for Foo*, not the
destructor for Foo.  Foo* is a built-in type, and its destructor is a
null operation.  There's no way that Foo* can have a private
destructor.

This is a compiler bug, nothing more.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Russ Williams <russw@io.com>
Date: 1997/03/01
Raw View
Is it legal to say:

class Foo;
vector <Foo*> v;

My understanding of STL is that this should be legal.  When v is
destroyed, any elements in it (which are pointers to Foo) are destroyed.
Destroying a built-in C pointer doesn't also destroy what the pointer
points at.  Yet my compiler (MSVC 4.2) complains; as near as I can tell,
it IS attempting to destroy the referents of the contained pointers, and
hence it complains since it has not seen a definition of Foo (and hence
Foo's destructor).

Interestingly, running the same code (with the MS headers) through
PC-Lint
yields no complaints about merely giving the class declaration without a
class definition.

BTW, the background for this is that I wish to have several different
containers all storing pointers or references of some sort to Foo
objects.
A given Foo object can appear in more than one container.  Hence I
do not want vector<Foo>, correct?  It seems evident I want something
like

vector <Foo *> all_foos;
vector <Foo *> red_foos;

// elsewhere in the program:

Foo a_red_foo; // will have its address added to both foo vectors
Foo a_blue_foo; // will only be added to all_foos

This raises another question: is it legal to say:

vector <Foo&> v;

or are reference types not legal parameter types?

thanks for any answers, as well as ideas of other approaches,
Russ

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: danm@ziplink.net (Dan Muller)
Date: 1997/03/03
Raw View
[This followup was posted to comp.std.c++ and a copy was sent to the
cited author.]

In article <fjh-970302-083716@cs.mu.oz.au>, russw@io.com says...
> Is it legal to say:
>
> class Foo;
> vector <Foo*> v;
>
> My understanding of STL is that this should be legal.  When v is
> destroyed, any elements in it (which are pointers to Foo) are destroyed.
> Destroying a built-in C pointer doesn't also destroy what the pointer
> points at.  Yet my compiler (MSVC 4.2) complains; as near as I can tell,
> it IS attempting to destroy the referents of the contained pointers, and
> hence it complains since it has not seen a definition of Foo (and hence
> Foo's destructor).

It might be helpful if you posted more of your code, and the compiler
errors.  What you're doing is perfectly legal, and I can't really see why
the compiler would complain; it shouldn't need to see the constructors or
destructors for Foo.

Hmm, I just tried the same thing with VC++ 4.2 and Rogue Wave's STL. I
got:

C:\STDLIB\INCLUDE\memory(139) : error C2027: use of undefined type 'Foo'

I don't really understand what's happening here. Providing a definition
of Foo that includes a private destructor allows it to compile, so it
can't be depending on access to the destructor. The logic for destruction
of the objects in vector<> is a bit more complex than I care to analyze
right now.

> BTW, the background for this is that I wish to have several different
> containers all storing pointers or references of some sort to Foo
> objects.
> A given Foo object can appear in more than one container.  Hence I
> do not want vector<Foo>, correct?  It seems evident I want something
> like
>
> vector <Foo *> all_foos;
> vector <Foo *> red_foos;
>
> // elsewhere in the program:
>
> Foo a_red_foo; // will have its address added to both foo vectors
> Foo a_blue_foo; // will only be added to all_foos

Yes, this works, but you have to be aware of a number of gotchas, which
are all discussed in several Web sites about the STL. For instance,
Mumit's "STL Newbie Guide" references a section on using pointers with
the STL.

http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html

The most obvious point, which you already know, is that you must manage
destruction yourself. More insidious is the fact that the generic
algorithms won't usually work as you might be expecting. For instance,
find() will compare the pointers rather than objects that they point to,
which is probably not what you want. Both problems can be worked around
in various ways, the most general being to create a handle class to use
instead of a pointer.

>
> This raises another question: is it legal to say:
>
> vector <Foo&> v;
>
> or are reference types not legal parameter types?

You can't use references in STL containers, because they need to be able
to modify the objects that they contain, and references can't be modified
once created. If you try it, you will likely get errors about references
to references, which are illegal in C++.

> thanks for any answers, as well as ideas of other approaches,

See the information about handle classes available on the Web, or pick up
any number of good books on advanced C++, because they all discuss this.
For instance (referenced from memory):
"More Effective C++" by Scott Meyers
"Advanced C++ Idioms" by Jim Coplien
--
Dan Muller   danm@ziplink.net
http://www.ziplink.net/~danm

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]






Author: Marcelo Cantos <marcelo@mds.rmit.edu.au>
Date: 1997/03/03
Raw View
Russ Williams wrote:
> class Foo;
> vector <Foo*> v;
> ...Yet my compiler (MSVC 4.2) complains...

This is probably a bug in your compiler.

> Interestingly, running the same code (with the MS headers) through
> PC-Lint
> yields no complaints about merely giving the class declaration without a
> class definition.

Nor should it.

> vector <Foo *> all_foos;
> vector <Foo *> red_foos;
>
> // elsewhere in the program:
>
> Foo a_red_foo; // will have its address added to both foo vectors
> Foo a_blue_foo; // will only be added to all_foos

Perfectly legal!


--
___________________________________________________________________
Marcelo Cantos, Research Assistant          marcelo@mds.rmit.edu.au
Multimedia Database Systems Group    __/_      _ Tel 61-3-9282-2497
723 Swanston St, Carlton VIC 3053, Aus/ralia ><_>Fax 61-3-9282-2490
                                     /
Acknowledgements: errors - me; wisdom - God; funding - RMIT

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Russ Williams <russw@io.com>
Date: 1997/03/04
Raw View
Thanks to all those who responded.  There seems to be universal
agreement that the code is legal.  (An unusual degree of agreement!)
Also thanks for the pointers to additional reading.

I'll contact the compiler vendor... or see if next version fixes it.

thanks
Russ

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]