Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

auto_ptr in STL container (Item 8) Scott Meyers

8 views
Skip to first unread message

axter

unread,
Sep 27, 2005, 12:25:21 PM9/27/05
to
Item#8 in Scott Meyers's book (Effective STL), he states the following:
*****************************************************************
Containers Of auto_ptr (COAPs) are prohibited. Code attempting to use
them shouldn't compile. The C++ Standardization Committe expended
untold effort to arrange for that to be the case. I shouldn't have to
say anything about COAPs, because your compiler should have plenty to
say about such containers, and all of it should be uncomplementary.

Alas, many programmers use STL platforms that fail to reject COAPs.
*****************************************************************


However, in reading the C++ standard, it only makes the following
reference on this issue:
*****************************************************************
Note: The uses of auto_ptr include providing temporary
exception-safety for dynamically allocated memory, passing
ownership of dynamically allocated memory to a function,
and returning dynamically allocated memory from a function.
auto_ptr does not meet the CopyConstructible and Assignable
requirements for Standard Library container elements and thus
instantiating a Standard Library container with an auto_ptr
results in undefined behavior. -end note.
*****************************************************************


The above seems to imply that it is possible to compile a STL container
of auto_ptr types.
I've been under the assumption that a fully compliant compiler/STL
implementation would not allow a STL container of auto_ptr types to
compile.

Can someone please clarify IAW C++ standard which is the case.
If a compiler/STL implementation allows a STL container of auto_ptr
types to compile, is that compliant with the standard?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Carl Barron

unread,
Sep 28, 2005, 4:18:28 AM9/28/05
to
In article <1127830025.9...@g14g2000cwa.googlegroups.com>,
axter <te...@axter.com> wrote:

>
> The above seems to imply that it is possible to compile a STL container
> of auto_ptr types.
> I've been under the assumption that a fully compliant compiler/STL
> implementation would not allow a STL container of auto_ptr types to
> compile.
>

> Can someone please clarify IAW C++ standard which is the case.
> If a compiler/STL implementation allows a STL container of auto_ptr
> types to compile, is that compliant with the standard?

If your compiler will compile anything the standard says is valid
then the compiler is 100% compliant.
If your code violates the restraints of the standard library
components that you use then your code is not compilant.

werasmus

unread,
Sep 28, 2005, 4:17:28 AM9/28/05
to

axter wrote:

> However, in reading the C++ standard, it only makes the following
> reference on this issue:
> *****************************************************************
> Note: The uses of auto_ptr include providing temporary
> exception-safety for dynamically allocated memory, passing
> ownership of dynamically allocated memory to a function,
> and returning dynamically allocated memory from a function.
> auto_ptr does not meet the CopyConstructible and Assignable
> requirements for Standard Library container elements and thus
> instantiating a Standard Library container with an auto_ptr
> results in undefined behavior. -end note.
> *****************************************************************
>
>
> The above seems to imply that it is possible to compile a STL container
> of auto_ptr types.

Not true. STL Containers store contained types by value (value
semantics). It is therefore required that the contained type should at
least have a copy constructor and (or) assignment operator - depending
on operations performed and the container type. If you takes as
example, one of the sequence containers (vector or list), then you
would notice (in the std) that for modifiers type T is passed as (const
T&).

example (from std):
void push_back( const T& x ); //or..
iterator insert( iterator pos, const T& x );

It should therefore be impossible to use std::auto_ptr<X> as type T, as
auto_ptr's copy constructor (and assignment op) requires (X& x) as
argument. It does not meet the copy-constructable requirements of the
container.

Hope this helps - it seems clear to me.

Regards,

Werner

Bo Persson

unread,
Sep 28, 2005, 5:46:05 AM9/28/05
to

"axter" <te...@axter.com> skrev i meddelandet
news:1127830025.9...@g14g2000cwa.googlegroups.com...

Most, if not all, will generate a compilation error. It's not required
though.

> Can someone please clarify IAW C++ standard which is the case.
> If a compiler/STL implementation allows a STL container of auto_ptr
> types to compile, is that compliant with the standard?
>

When the standard says that it is undefined behaviour, it explicitly
puts no requirements on an implementation. If it did, it wouldn't be
undefined anymore...


Bo Persson

Tommaso Galleri

unread,
Sep 28, 2005, 5:50:31 AM9/28/05
to
"axter" <te...@axter.com> wrote

> I've been under the assumption that a fully compliant compiler/STL
> implementation would not allow a STL container of auto_ptr types to
> compile.
>
> Can someone please clarify IAW C++ standard which is the case.
> If a compiler/STL implementation allows a STL container of auto_ptr
> types to compile, is that compliant with the standard?

this is "legal":
vector< auto_ptr<int> > vaptr;

this is not:
vector< auto_ptr<int> > vaptr(n);
and even if you used the first form, this is not:
vaptr.push_back(auto_ptr<int>(new int()));

in other words, it has to do with the fact that STL containers take
const references.
for example:
void push_back(const T& x);
and for the same reason why you cannot do:

const auto_ptr<int> a1( new int() );
auto_ptr<int> a2( a1 );

you also cannot use vector::pushack, and if you do it's compile time
error.

Note that if you remove the keyword "const" from the last example the
code compiles.
The issue here is that the object a1 "changes state" and no longer owns
the object (ownership has been transferred to a2).
Since a1 "changes" it makes sense that if a1 is const such "change"
should not be allowed. This is why if a1 is const the code does not
compile.

The same applies to:

const auto_ptr<int> a1( new int() );
auto_ptr<int> a2;
a2 = a1;

Now apply the same idea to push_back; this receives a const reference.
So far it's legal, but inside push_back x is *const* reference.
The code will then try to do something like:
whatever = x;
to copy the auto_ptr into the vector. This will fail to compile.

Sorry if I have not been to precise, but I hopefully this should clarify
you doubts.

HTH,

Tommaso Galleri


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

Ismail Pazarbasi

unread,
Sep 28, 2005, 5:51:55 AM9/28/05
to
It says:

...and thus


instantiating a Standard Library container with an auto_ptr

_results in undefined behavior_. (repeat, undefined behavior).

It may vary from one implementation to another. But from standard's
point of view, which you should rely on, it's clearly undefined.

Does vendor of your compiler/STL implementation guarantee that they are
going to provide the same behavior in its next version? If standard
says something is undefined, do not rely on what one specific
compiler/STL implementation does. I don't know whether you have a
portability concern. If you have, you may not use your code on another
platform with another compiler and STL. You may not even use your code
with next version of compiler or STL.

Ismail

axter

unread,
Sep 28, 2005, 9:52:29 AM9/28/05
to

Now I get it, and I now realize that Scott Meyers's comments and the
C++ standard statement are actually not in conflict with each other.
The standard is saying only instantiating this type results in
undefined behavior, where-as Scott Meyers is saying that trying to use
this type should result in a compile time error IAW C++ standard.
And by using, he means calling any member method that will actually put
an auto_ptr into the container.

So the bottom line is that IAW C++ standard, calling any method that
would put an auto_ptr into an STL container should result in a compile
time error.

Thank you both werasmus and Tommaso Galleri for the insightful
clarification.

kanze

unread,
Sep 28, 2005, 9:53:56 AM9/28/05
to
Tommaso Galleri wrote:
> "axter" <te...@axter.com> wrote

> > I've been under the assumption that a fully compliant
> > compiler/STL implementation would not allow a STL container
> > of auto_ptr types to compile.

> > Can someone please clarify IAW C++ standard which is the
> > case. If a compiler/STL implementation allows a STL
> > container of auto_ptr types to compile, is that compliant
> > with the standard?

> this is "legal":
> vector< auto_ptr<int> > vaptr;

No it's not. The standard says that it is undefined behavior.
It may compile; it may even not crash on execution. But it is
still illegal.

> this is not:
> vector< auto_ptr<int> > vaptr(n);
> and even if you used the first form, this is not:
> vaptr.push_back(auto_ptr<int>(new int()));

> in other words, it has to do with the fact that STL containers
> take const references.

Not really, although you have a sort of a point. The reason
that it is illegal is that auto_ptr doesn't meet the given
constraints for a type which is a member of a container: it's
not CopyConstructable nor Assignable, according to the
definition of those constraints.

If you look at the definition of auto_ptr, you will see that it
uses considerable gymnastics to make copies. The whole point of
the gymnastics, of course, is to allow copying temporary objects
(which can't bind to a non-const reference) while making it
highly probable that the compiler will detect something wrong if
you try to instantiate an STL container with it.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

kanze

unread,
Sep 28, 2005, 9:53:35 AM9/28/05
to

All the above says, of course, is that you shouldn't use an STL
container of auto_ptr types. That the standard makes no
statement as to what will happen if you do: it may fail to
compile; it may compile, but crash on execution; it may work
like you expect; it may, in fact, do just about anything.

> > I've been under the assumption that a fully compliant
> > compiler/STL implementation would not allow a STL container
> > of auto_ptr types to compile.

> Most, if not all, will generate a compilation error. It's not
> required though.

> > Can someone please clarify IAW C++ standard which is the
> > case. If a compiler/STL implementation allows a STL
> > container of auto_ptr types to compile, is that compliant
> > with the standard?

> When the standard says that it is undefined behaviour, it
> explicitly puts no requirements on an implementation. If it
> did, it wouldn't be undefined anymore...

It's probably worth pointing out, however, that the standards
committee did modify auto_ptr considerably to make it easy for
implementations to fail to compile in this case. With the
original specification, it was almost impossible to create an
implementation which would fail to compile, although it would
usually do a few things wrong during execution. (Not
everything, of course. That would be too easy:-).)

Given this, from a quality of implementation point of view, I
would expect an implementation to fail to compile. Except maybe
if all you did was declare an empty container, and then never
use it.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Tommaso Galleri

unread,
Sep 28, 2005, 10:48:30 AM9/28/05
to
"kanze" <ka...@gabi-soft.fr> wrote

> > this is "legal":
> > vector< auto_ptr<int> > vaptr;

> No it's not. The standard says that it is undefined behavior.
> It may compile; it may even not crash on execution. But it is
> still illegal.

ok, that is of course what I meant (but my choice of words has not been
very fortunate ;-)



> Not really, although you have a sort of a point. The reason
> that it is illegal is that auto_ptr doesn't meet the given
> constraints for a type which is a member of a container: it's
> not CopyConstructable nor Assignable, according to the
> definition of those constraints.

Here I was not discussing why it's illegal, but why it does not compile.
The fact that it's not CopyConstructable and Assignable is so important
that this alone is enough for not using a container of auto_ptr and to
make this illegal.
However, in practice, the code does not fail to compile because the
above two properties are not met, this is what I was trying to explain.

Cheers,

Tommaso


--
Posted via Mailgate.ORG Server - http://www.Mailgate.ORG

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

0 new messages