C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

question on std::vector default ctor
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
harkness
Guest





PostPosted: Mon Dec 08, 2003 11:00 pm    Post subject: question on std::vector default ctor Reply with quote



In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the default ctor was called only once. Which of the
following is true?

1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of

TIA (test program follows)
// vectorsize.cpp -- example of sizing a vector

#include <vector>
using std::vector;

#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

// poor man's profiler I got from Dr. Cargill
#define DOTRACE
#include "Trace.h"

class MyClass
{
public:
MyClass();
friend ostream& operator<<(ostream& os, const MyClass& mc);

private:
int m_i;
};

int globali(0);

MyClass::MyClass()
{
TRACE("MyClass", "Default ctor");

cout << "assigning m_i" << endl;
m_i = globali++;
}

ostream& operator<<(ostream& os, const MyClass& mc)
{
os << mc.m_i;
return os;
}

typedef vector typedef MVector::const_iterator MCIter;

int main()
{
srand(1); // seed

MVector mv(Cool; // create and initialize
// should call default ctor 8 times

int i=-1;

for(MCIter iter = mv.begin(); iter != mv.end(); ++iter)
{
cout << "mv[" << ++i << "]=" << *iter << endl;
}
return 0;
}

Output, showing only one ctor call:
..entering:MyClass Default ctor
assigning m_i
..exiting: MyClass Default ctor
mv[0]=0
mv[1]=0
mv[2]=0
mv[3]=0
mv[4]=0
mv[5]=0
mv[6]=0
mv[7]=0

--
Howard

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





PostPosted: Tue Dec 09, 2003 11:03 am    Post subject: Re: question on std::vector default ctor Reply with quote



"harkness" <harkness (AT) mail (DOT) ev1.net> skrev i meddelandet
news:200312081249.AA185925764 (AT) mail (DOT) ev1.net...
Quote:
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this using
gcc 3.2, and the default ctor was called only once. Which of the
following is true?

1) Josuttis was mistaken

Yes, I think so. The constructor used above is:
explicit vector(size_type n, const T& value = T(), const Allocator& =
Allocator());

It creates a temporary T which is used to copy initialize the 5 elements in
the vector. The default ctor should be called once and the copy ctor five
times.

--
Dag Henriksson



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

Back to top
Francis Glassborow
Guest





PostPosted: Tue Dec 09, 2003 5:09 pm    Post subject: Re: question on std::vector default ctor Reply with quote



In article <v07atvoifjvuek2kqmsfa1p1vjcsaq0p3a (AT) 4ax (DOT) com>, Howard
<hlh_nospam (AT) iwon (DOT) com> writes
Quote:
I didn't see anything in Stroustrup about this, and so far, I haven't
turned anything up with a websearch. I can't imagine that I'm the
only person to run across this. I guess it's time to break down and
order my copy of the standard.

What the Standard requires is that the ctor for vector<T> make n calls
to the copy ctor for T to copy the argument passed to the second
(defaulted) reference parameter of the vector ctor. The default is a
value initialised instance of T (i.e. T()).

It is common (if not universal) that the compiler generated copy ctor
for a POD is simply a call of memcpy. Try using a T with an instrumented
copy ctor and you will see what happens (though now it will no longer be
using memcpy, unless you do so within the copy ctor.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit


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

Back to top
Roger Orr
Guest





PostPosted: Tue Dec 09, 2003 7:59 pm    Post subject: Re: question on std::vector default ctor Reply with quote

"Dag Henriksson" <dag.henriksson (AT) quidsoft (DOT) se> wrote

Quote:
"harkness" <harkness (AT) mail (DOT) ev1.net> skrev i meddelandet
news:200312081249.AA185925764 (AT) mail (DOT) ev1.net...
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that

std::vector<T> v(5);

[snip]

Quote:
The constructor used above is:
explicit vector(size_type n, const T& value = T(), const Allocator& =
Allocator());

It creates a temporary T which is used to copy initialize the 5 elements
in
the vector. The default ctor should be called once and the copy ctor five
times.

I would certain expect any sensible implementation would do this - but I
can't actually find anything in the standard which mandates this.
There don't seem to be any explicit complexity guarantees for this
std::vector constructor.

Roger Orr
--
MVP in C++ at www.brainbench.com



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

Back to top
Randy Maddox
Guest





PostPosted: Tue Dec 09, 2003 8:08 pm    Post subject: Re: question on std::vector default ctor Reply with quote

"harkness" <harkness (AT) mail (DOT) ev1.net> wrote

Quote:
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the default ctor was called only once. Which of the
following is true?

1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of


Look at the ctor you are using:

explicit vector(size_type n,
const T & value = T(),
const Allocator & allocator = Allocator);

Since you are passing only the size_type n argument the others
default. So the default ctor for T is called once and the copy ctor
for T is called 5 times.

Randy.

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

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Dec 09, 2003 8:09 pm    Post subject: Re: question on std::vector default ctor Reply with quote

"harkness" <harkness (AT) mail (DOT) ev1.net> wrote


Quote:
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this
using gcc 3.2, and the default ctor was called only once. Which of the
following is true?

1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of

If this is actually what Josuttis wrote, he is mistaken. (He actually
wrote the book some time ago, when the library was still in a state of
flux, but I don't think that this point has changed.) Your statement is
the equivalent of:

std::vector< T > v( 5, T() ) ;

In this statement, the standard requires the default constructor to be
called once, and the copy constructor to be called 5 times.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

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

Back to top
John Potter
Guest





PostPosted: Tue Dec 09, 2003 8:10 pm    Post subject: Re: question on std::vector default ctor Reply with quote

On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:

Quote:
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
default ctor was called only once. Which of the following is true?

1) Josuttis was mistaken

The above uses the ctor with a defaulted T(). There is no vector ctor
that takes only a size_type.

std::vector<T> v(5, T());

Now table 67 states that the sequence is constructed from n copies of
the supplied t. Instrument your copy ctor to see the copies.

Disclaimer: This could be written as two ctors with one taking a
size_type and the other taking a size_type and a T. I can't find
anything which allows or forbids using n default constructions in the
case of the size_type only ctor. However, there is nothing which
requires n default constructions.

John

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

Back to top
Gabriel Dos Reis
Guest





PostPosted: Tue Dec 09, 2003 10:06 pm    Post subject: Re: question on std::vector default ctor Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] writes:

Quote:
"harkness" <harkness (AT) mail (DOT) ev1.net> wrote in message
news:<200312081249.AA185925764 (AT) mail (DOT) ev1.net>...

In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this
using gcc 3.2, and the default ctor was called only once. Which of the
following is true?

1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of

If this is actually what Josuttis wrote, he is mistaken. (He actually
wrote the book some time ago, when the library was still in a state of
flux, but I don't think that this point has changed.) Your statement is
the equivalent of:

std::vector< T > v( 5, T() ) ;

That form is permitted, but it is not a requirement.

Quote:
In this statement, the standard requires the default constructor to be
called once, and the copy constructor to be called 5 times.

This is wrong. The Standard does not require the default constructor
to be called once and the copy constructor to be called 5 times.
Rather, the Standard permits both behaviour.

--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]

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

Back to top
Gabriel Dos Reis
Guest





PostPosted: Tue Dec 09, 2003 10:11 pm    Post subject: Re: question on std::vector default ctor Reply with quote

John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

Quote:
On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:

In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that

std::vector<T> v(5);

calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
default ctor was called only once. Which of the following is true?

1) Josuttis was mistaken

The above uses the ctor with a defaulted T(). There is no vector ctor
that takes only a size_type.

std::vector<T> v(5, T());

Now table 67 states that the sequence is constructed from n copies of
the supplied t. Instrument your copy ctor to see the copies.

Disclaimer: This could be written as two ctors with one taking a
size_type and the other taking a size_type and a T. I can't find
anything which allows or forbids using n default constructions in the
case of the size_type only ctor. However, there is nothing which
requires n default constructions.

The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.

--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]

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

Back to top
John Potter
Guest





PostPosted: Wed Dec 10, 2003 11:17 am    Post subject: Re: question on std::vector default ctor Reply with quote

On 9 Dec 2003 17:11:50 -0500, Gabriel Dos Reis
<gdr (AT) integrable-solutions (DOT) net> wrote:

Quote:
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in the
| case of the size_type only ctor. However, there is nothing which
| requires n default constructions.

The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.

I thought I said that. If it does, it could either default construct
one item and copy construct N from it or default construct N. Or can
it? It must use the allocator. How do you default construct using an
allocator? The member and uninitialized_X algorithms all copy
construct. Is it allowed to use placement new in allocated space?

John

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

Back to top
Bjarne Stroustrup
Guest





PostPosted: Wed Dec 10, 2003 11:25 am    Post subject: Re: question on std::vector default ctor Reply with quote

Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote

Quote:
In article <v07atvoifjvuek2kqmsfa1p1vjcsaq0p3a (AT) 4ax (DOT) com>, Howard
[email]hlh_nospam (AT) iwon (DOT) com[/email]> writes
I didn't see anything in Stroustrup about this, and so far, I haven't
turned anything up with a websearch. I can't imagine that I'm the
only person to run across this. I guess it's time to break down and
order my copy of the standard.

What the Standard requires is that the ctor for vector<T> make n calls
to the copy ctor for T to copy the argument passed to the second
(defaulted) reference parameter of the vector ctor. The default is a
value initialised instance of T (i.e. T()).

It is common (if not universal) that the compiler generated copy ctor
for a POD is simply a call of memcpy. Try using a T with an instrumented
copy ctor and you will see what happens (though now it will no longer be
using memcpy, unless you do so within the copy ctor.

That's correct, but I'd like my 2 cents about the "I didn't see
anything in Stroustrup about this".

On pg 447 there is a coment "n copies of val" and a paragraph that
elements are initialized by the default constructor of the element
type that I suspect could easily be misread. Luckily, pg 944 I happen
to use exactly the initialize-with-n-copies-of-val constructor for
vector as an illustration of exception safety techniques, so you can
see what is done and how.

- Bjarne Stroustrup; http://www.research.att.com/~bs

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

Back to top
James Dennett
Guest





PostPosted: Wed Dec 10, 2003 11:38 am    Post subject: Re: question on std::vector default ctor Reply with quote

Gabriel Dos Reis wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr writes:

| "harkness" <harkness (AT) mail (DOT) ev1.net> wrote in message
| news:<200312081249.AA185925764 (AT) mail (DOT) ev1.net>...
|
| > In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
| > that
|
| > std::vector<T> v(5);
|
| > calls the default ctor of T 5 times. I wrote a test case for this
| > using gcc 3.2, and the default ctor was called only once. Which of the
| > following is true?
|
| > 1) Josuttis was mistaken
| > 2) The standard has changed
| > 3) This is a gcc 3.2 bug (optimization?)
| > 4) It's due to some other reason I haven't thought of
|
| If this is actually what Josuttis wrote, he is mistaken. (He actually
| wrote the book some time ago, when the library was still in a state of
| flux, but I don't think that this point has changed.) Your statement is
| the equivalent of:
|
| std::vector< T > v( 5, T() ) ;

That form is permitted, but it is not a requirement.


How so? There is no single-argument constructor taking
an integral value directly specified: while the library
may be allowed to add one, its behaviour must surely still
be as if the version with a default argument were used --
and that version cannot rely on being able to use the
default constructor, as it must work with types which have
no default constructor.

All I see is that

Quote:
| In this statement, the standard requires the default constructor to be
| called once, and the copy constructor to be called 5 times.

This is wrong. The Standard does not require the default constructor
to be called once and the copy constructor to be called 5 times.
Rather, the Standard permits both behaviour.


How so? Where is the freedom to do this (which is beyond
the "as if" rule) granted?

I do accept that you may well know of rules that I don't
recall, or might not have been aware of -- if so, I would
like to fill one more gap in my knowledge.

I think James Kanze's expectation is that there is an
equivalence by definition between the form

std::vector<T> v(5);

and

std::vector<T> v(5, T());

and I find that expectation a reasonable one based on my
reading of the standard.

-- James.

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

Back to top
James Dennett
Guest





PostPosted: Wed Dec 10, 2003 11:39 am    Post subject: Re: question on std::vector default ctor Reply with quote

Gabriel Dos Reis wrote:

Quote:
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

| On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:
|
| > In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
|
| > std::vector<T> v(5);
|
| > calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
| > default ctor was called only once. Which of the following is true?
|
| > 1) Josuttis was mistaken
|
| The above uses the ctor with a defaulted T(). There is no vector ctor
| that takes only a size_type.
|
| std::vector<T> v(5, T());
|
| Now table 67 states that the sequence is constructed from n copies of
| the supplied t. Instrument your copy ctor to see the copies.
|
| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in the
| case of the size_type only ctor. However, there is nothing which
| requires n default constructions.

The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.

So long as the effects of calling those separate functions are

the same (up to the usual "as if" games) as would be achieved
were a single member with default arguments used and called,
no?

Granted, a user can often tell the difference with regular
member functions (e.g. by trying to take the address of one,
cast to a suitable type to detect its presence) but I would
expect that the effect of calling a substituted function
should be the same as calling the version explicitly defined
by the standard.

-- James.

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

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Dec 10, 2003 3:59 pm    Post subject: Re: question on std::vector default ctor Reply with quote

Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> wrote

Quote:
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:

| On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:

| > In _The C++ Standard Library_ by Josuttis, page 149, is the
| > assertion that std::vector<T> v(5);

| > calls the default ctor of T 5 times. I wrote a test case for this
| > using gcc 3.2, and the default ctor was called only once. Which
| > of the following is true?

| > 1) Josuttis was mistaken

| The above uses the ctor with a defaulted T(). There is no vector
| ctor that takes only a size_type.

| std::vector<T> v(5, T());

| Now table 67 states that the sequence is constructed from n copies
| of the supplied t. Instrument your copy ctor to see the copies.

| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in
| the case of the size_type only ctor. However, there is nothing
| which requires n default constructions.

The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.

True, but it doesn't authorize different semantics for the two
variants. If an implementation splits the two, it must still ensure
that the std::vector<T>::vector( size_t ) constructor meets the
requirements given in table 67 for X(n, t), in particular, that it
"constructs a sequence with n copies of t".

The wording could definitly be more precise, but since calling the copy
constructor could have observable behavior, and there is no special
wording to allow eliding it here, so I would interpret this requirement
to mean that the copy constructor must be called at least n times. I'm
far from sure that this is the intent, but it is definitly a reasonable
interpretation of what the standard actually says.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

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

Back to top
Daniel Krügler (nee Spang
Guest





PostPosted: Wed Dec 10, 2003 4:14 pm    Post subject: Re: question on std::vector default ctor Reply with quote

Hello, John Potter!

John Potter schrieb:

Quote:
I thought I said that. If it does, it could either default construct
one item and copy construct N from it or default construct N. Or can
it? It must use the allocator. How do you default construct using an
allocator? The member and uninitialized_X algorithms all copy
construct. Is it allowed to use placement new in allocated space?

Actually some days ago I stumbled about the same restriction of
std::allocator.
To my opinion its interface should be extended to allow placement new
default construction (construct(T*) overload). The reason is: Also the
Standard Libary Container Classes does require CopyConstructible
as an property of its contents, this might have different performance and
exception guarantees.
Could we demand, that construct(T*) does either not exist or its call
should not be a well-defined expression, in case of classes, which don't
provide the DefaultConstructible requirement? (SFINAE might help here)

Greetings from Bremen,

Daniel




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

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.