Topic: Avoiding zero-initialization in containers of built-in types


Author: "Sean Carson" <carson@cgo.wave.ca>
Date: 2000/01/02
Raw View
I would welcome clarification, since my understanding is that there is no
formal initialization behaviour defined wrt a POD in local scope, hence no
definition of any use of an unitialized POD...
?
Thanks for all replies,
Sean Carson.


"William H. Bloodworth" <whbloodworth@usa.net> wrote in message
news:386c1cf9.16944344@news.airmail.net...
> > ... partial post ...
> >Your example above is just fine.  What's undefined is
> >
> > int main()
> > {
> > double d, e;
> > e = d; /* might crash, either in C or C++ */
> > return 0;
> > }
> I do not wish to disagree...I would just like an explaination of "why" there is
> undefined behavior when assigning one uninitialized POD to another.  Would you please
> expand upon your post further.

[ moderator's note: excessive quoting removed. Please trim
  unnecessary material from the reply. -sdc ]


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: whbloodworth@usa.net (William H. Bloodworth)
Date: 1999/12/31
Raw View
> ... partial post ...
>Your example above is just fine.  What's undefined is
>
> int main()
> {
>  double d, e;
>  e = d;  /* might crash, either in C or C++ */
>  return 0;
> }
I do not wish to disagree...I would just like an explaination of "why" there is
undefined behavior when assigning one uninitialized POD to another.  Would you please
expand upon your post further.

Thank you,

W. Bloodworth

==========================================================================
= Great Achievement REQUIRES Great Effort.
=
= William H. Bloodworth - whbloodworth@usa."net" - Maxim Group Consultant
==========================================================================
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/01/02
Raw View
In article <386c1cf9.16944344@news.airmail.net>, William H. Bloodworth
<whbloodworth@usa.net> writes
>I do not wish to disagree...I would just like an explaination of "why" there is
>undefined behavior when assigning one uninitialized POD to another.  Would you
>please
>expand upon your post further.

Let me.  Except in the case of char types all other types may include
trap representations, what happens in such circumstances is up to the
compiler implementor.  Indeed the trap might even be at system level and
so outside the control of the implementor.  (I believe Windows NT has a
pattern that it stamps on uninitialised memory though it doesn't, AFAIK,
do anything weird if you use such values.  At least one debugging C
compiler that I know calls the debugger if you try to read an
unitialised value)

It may appear harmless to read an unitialised double, but the Standard
takes the simple option of only providing special treatment for char
types.


>
>Thank you,
>
>W. Bloodworth

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: kanze@gabi-soft.de
Date: 2000/01/02
Raw View
whbloodworth@usa.net (William H. Bloodworth) writes:

|>  > ... partial post ...
|>  >Your example above is just fine.  What's undefined is

|>  > int main()
|>  > {
|>  >  double d, e;
|>  >  e = d;  /* might crash, either in C or C++ */
|>  >  return 0;
|>  > }

|>  I do not wish to disagree...I would just like an explaination of
|>  "why" there is undefined behavior when assigning one uninitialized
|>  POD to another.  Would you please expand upon your post further.

The undefined behavior is because of the access of an uninitialized
double value.  It has nothing to do with the fact that the access is for
assignment -- a compiler for a processor with separate floating point
load and store instructions might generate a floating point load and
store in this case, for example, and loading an uninitialized double
could easily generate a trap.

--
James Kanze                         mailto:James.Kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                  Beratung in Objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/11/27
Raw View
Darin Adler <darin@bentspoon.com> wrote:

>As has been discussed previously in other threads in this newsgroup, default
>initialization of a POD-struct results in default initialization of all the
>members because of paragraph 8.5/9 in the C++ standard. That means that if
>you default-initialize a "Dave Abraham's code" Int then x is also
>default-initialized, yielding an initial value of 0.

Wouldn't an array of POD types then default-initialize all of its
elements? Wouldn't the initialization overhead thus apply equally to
arrays and vectors? What am I missing?

-------------------------------------------------------------
Pablo Halpern                            phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch
http://www.halpernwightsoftware.com/stdlib-scratch
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/28
Raw View
Pablo Halpern <phalpern@newview.org> wrote:

> Darin Adler <darin@bentspoon.com> wrote:
>
> >As has been discussed previously in other threads in this newsgroup, default
> >initialization of a POD-struct results in default initialization of all the
> >members because of paragraph 8.5/9 in the C++ standard. That means that if
> >you default-initialize a "Dave Abraham's code" Int then x is also
> >default-initialized, yielding an initial value of 0.
>
> Wouldn't an array of POD types then default-initialize all of its
> elements? Wouldn't the initialization overhead thus apply equally to
> arrays and vectors? What am I missing?

struct POD { int i[421; double d[999]; };

// Reference 5.3.4/p.15

new POD;    // not initialized
new POD();  // default initialized

new POD[10000]; // not initialized

vector<POD> v(10000);       // same as:
vector<POD> w(10000, POD()> // copy initialized
            // from default initialized instance

-- J   rg Barfurth


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/11/24
Raw View
smeyers@aristeia.com (Scott Meyers) wrote:

>
>FWIW, my reason for asking is that I *like* the STL and I'd like to be able
>to convince more people to use it.  But I can't in good conscience tell
>people about the benefits of vector without also disclosing that they must
>pay to initialize the contents of the vector, even if such initialization
>is unnecessary.  In C, there is malloc and there is calloc, and callers
>choose the one most appropriate for their needs.  With the STL, it seems,
>all we have is the moral equivalent of calloc.  If that's the way it is,
>then fine, that's the way it is, but let's not try to disguise it.  For
>some people, it will make a difference.

There's a lot more to STL than just container types. You can still show
them how cool it is that you can use pointers into an array as iterators
to call standard algorithms. Built-in arrays are still the best thing to
use in some circumstances.

>I was simply hoping I'd overlooked something and there *was* a way to
>create a vector<int> of size n without initializing the ints in the
>vector.  It seems that there isn't.  Oh well.

If the array is given a fixed size on initialization, I guess you can
create your own allocator type that has a do-nothing construct()
function. This will break if you do anything to change the size of the
vector after creation. Will doing this extra work will convince more
people that the STL is good? I doubt it. Fixed-sized containers are
classic uses of arrays.

On the other hand, people suggested creating your own vector-like
container class that does what you want. If you do this work or (better
yet) find something like it on the 'Net, you might impress people with
how flexible and extensible the STL part of the Standard Library is.

-------------------------------------------------------------
Pablo Halpern                            phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch
http://www.halpernwightsoftware.com/stdlib-scratch
I am self-employed. Therefore, my opinions *do* represent
those of my employer.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/11/23
Raw View
In article <s3c2fskr3ef26@news.supernews.com>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
>
> <niklasb@my-deja.com> wrote in message
> news:80ppte$ipl$1@nnrp1.deja.com...
> > I suspect you hit the nail on the head here: memory allocation
> > probably accounts for virtually all of the time difference
> > observed by the original poster. I doubt zero-initialization
> > was a significant factor.
>
> I guess this depends upon the size of the memory allocated. For many
> allocators, the size allocated doesn't influence a lot the time spent
> for allocation, but filling the memory is O(n).

I think the vectors in this particular example were small.
The original poster referred to a "26-way tree to store a
dictionary", where each node could contain either a vector
of 26 pointers or an array of 26 pointers.

Since the design fixes the array size at 26, and a vector
of pointers does not "own" the objects pointed to, I see
no advantage to using a vector in this case. But there is
a cost: an extra memory allocation per node.

The original poster said he tried both approaches and the
vector version took 50% longer to load the disctionary.
I suspect the memory allocation overhead would account for
most of this; I doubt that zero-initializing the pointers
in each vector would be a significant factor.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: " " <jack_reeves@ibm.net>
Date: 1999/11/21
Raw View
At the risk of repeating everything everybody has already said. I would like
to
summarize.

> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data in
> > the container?
>

A. If you have a "known-at-compile-time" size, an array allocated on the
stack is going to always be more efficient than a vector (unless your
free-store manager is VERRY good).

B. If you wish a vector interface on such an array, you can certainly create
a template that will do that. When people look askance at the idea of
creating their own containers, or even start to criticize the STL because it
doesn't meet their exact requirements, I point out that "one size doesn't
fit all" is part of the reason that C/C++ has more than one size of integer.
If it could be used more than once or twice, then the effort to create it is
easily justified. I don't have such a vector in my collection, but I do have
such a string, and that is a much bigger interface. Nevertheless, for people
to whom efficiency is paramount, they are often better off sticking with
arrays and C style coding - if for no other reason than that way they only
have themselves to blame, and their own code to tune, when things aren't
good enough.

C. Assuming that you have a dynamically allocated array the question is: can
you avoid the copy initialization overhead that occurs in
    vector<int> v(10);
The answer is: only if you do your own initialization, either in the
constructor, or via assign on an un-initialized vector.
    vector<int> v(first, last);
or
    vector<int> v;
    v.assign(first, last);
I am assuming that if 'first' & 'last' are random access iterators a
competent vector implementation will do the equivalent of
reserve(last-first) in both cases.

So that leaves the question of where do I get iterators that do my
initialization?
Well, here is my $0.02 worth. When I was first learning the STL (and
patterns) I realized iterators did not have to be attached to a container.
So I created my own
    sequence_iterator;

(Sorry, I don't have that code on my laptop, so I am not going to try to
reproduce it).
My original intent was to be able to plug in any kind of sequence generating
function, such as a random number generator for example, and then generate
the sequence with the iterator. After several versions, I ended up with
sequence_iterator being a very simple type that would simply generate
integers in sequence like so:
    copy(sequence_iterator(0), sequence_iterator(10), back_inserter(v));
to initialize a vector with the numbers [0,10).

I had had a hard time figuring out how to create an iterator to mark the end
of a random number sequence, other than just to count the number of times it
was invoked, so I abstracted that out. Then I created

    template <class Iter, class Op> transform_iterator;
This takes an iterator, and a unary_function object. Its dereference
operator applies the functor to the value from the internal iterator
    operator*() { return _op(*_it); }

I originally created this for other purposes, for which it did not turn out
to be too useful. Its only real use is with sequence_iterator,  but I keep
them as separate classes. So given
    struct square_op : unary_function<int, int> {
        int operator()(int i) const { return i * i; }
    }

    typedef transform_iterator<sequence_iterator, square_op> Init;
    vector v(Init(0), Init(10));

Should come pretty close to the desired efficiency.

As has been pointed out, this only works for initialization that can be done
in sequence. If you need random order initialization, you are out of luck.
It also requires that you can express the sequence in a functor that takes
an 'int' as an argument. It doesn't have to do anything with the int
however, and it can return any type.

For initializing one array, this seems like a pain even to me, and I have
the two iterator adapters already sitting around.
For situations where a number of these things need to be created in
different places so that you start to get some reuse out of the typedefs and
the functors you have to write then I think this rapidly becomes the
preferred way to do this.

Jack Reeves





      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/19
Raw View
In article <hinnant-1211991022270001@ith3-4cc.twcny.rr.com>,
  hinnant@anti-spam_metrowerks.com (Howard Hinnant) wrote:

> > With a decent
> > implementation:
> >
> >         std::vector<int> v();
> >         v.reserve(10);
> >         for(int i=0; i<10; i++)
> >                 v.push_back(i);
> >
> > should do the job.

> Not quite as efficient as what I wrote.  The iterator constructor
> doesn't have to keep checking internals after every "push_back".  Note
> that this is true only if the iterator is not limited to being an
> input iterator, which is why I hacked it up as a random access type.

If all of the functions are inline, a good compiler should be able to
optimize this to the same code as would be generated for initializing a
built-in array.  A very good compiler could, anyway -- I don't think
I've seen one that good yet.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/19
Raw View
In article <MPG.12954f55bd8638199896f6@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:
> On 11 Nov 1999 21:02:43 GMT, James Kuyper Jr. wrote:

> > Call v.reserve() to do the equivalent of new[], then call
> > v.push_back() or v.insert(end(),) when you can actually generate the
> > initializing values. This should have pretty close to the same
> > efficiency as what you'd like.

> Perhaps.  I'd expect a test of size against capacity for each
> insertion.  If n is big, that's a lot of tests.

Theoretically, as I pointed out in another posting, if all of the
functions are inline, the compiler should be able to optimize the extra
tests, etc. away.

Practically, don't hold your breath.

> FWIW, this posting (to clcm) is what got me interested in this whole
> matter:

>   Subject: vector vs array
>   Date: 1999/08/09
>   Author: Jak Kirman <jak@hayley.cs.brown.edu>

>   Is it reasonable to assert that one should *always* use vectors
rather
>   than arrays?

Is it ever reasonable to assert anything with *always* (or never)?

>   If I am implementing a 26-way tree to store a dictionary, for
>   example, and I know that porting to a different natural language
>   will require a complete redesign of this portion of my program, it
>   seems reasonable to me to use an array of 26 pointers rather than a
>   vector of the same.

>   In one particular application where I tried the two, I found that
>   loading the dictionary took about 50% longer with vectors than
>   arrays, even though I was specifying the size of the vector at
>   creation time.

>   Are there any significant reasons for preferring to use vector over
>   plain arrays despite this performance degradation?

> This suggests that for at least one combination of application,
> compiler, and library implemenation, use of vector<T*> is
> significantly slower than use of T[n].  This is hardly conclusive, of
> course, because my guess is that his array implementation was on the
> stack and a vector's data is on the heap, but still, it makes one
> wonder.  Or at least it makes me wonder.

Wonder about what?  I would fully expect that for most implementations,
the exact timings for vector and the built in array will differ for a
particular set of operations.  And it certainly wouldn't surprise me if
in certain cases, array is faster -- any time you could put the array on
the stack, the contrary results would surprise me.  It also doesn't
surprise me that there exist specific applications where this difference
makes a difference, maybe even an important difference.  In such cases,
you do what you have to do to meet the specs.

In this case, if the arrays are on the stack, as you suspect, then I'm
surprised that it only took 50% longer.  Whether the 50% is a problem or
not depends on the application: 150 ms instead of 100 ms will rarely be
a problem: 3 sec. instead of 2 maybe, and 3 days instead of 2 means not
being able to run the job over the week-end.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/20
Raw View
<niklasb@my-deja.com> wrote in message
news:80ppte$ipl$1@nnrp1.deja.com...
> I suspect you hit the nail on the head here: memory allocation
> probably accounts for virtually all of the time difference
> observed by the original poster. I doubt zero-initialization
> was a significant factor.

I guess this depends upon the size of the memory allocated. For many
allocators, the size allocated doesn't influence a lot the time spent
for allocation, but filling the memory is O(n).


Andrei



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/11/17
Raw View
In article <MPG.12954f55bd8638199896f6@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:

[snip]

> FWIW, this posting (to clcm) is what got me interested in this whole
> matter:

[quotation snipped]

> This suggests that for at least one combination of application,
compiler,
> and library implemenation, use of vector<T*> is significantly slower
than
> use of T[n].  This is hardly conclusive, of course, because my guess
is
> that his array implementation was on the stack and a vector's data is
on
> the heap, but still, it makes one wonder.  Or at least it makes me
wonder.

I suspect you hit the nail on the head here: memory allocation
probably accounts for virtually all of the time difference
observed by the original poster. I doubt zero-initialization
was a significant factor.

Nevertheless, I too have sometimes wondered whether it might
be possible to bypass initialization in cases like this:

  std::vector<int> vec;
  vec.uninitialized_resize(n);
  n = fread(vec.begin(), sizeof(int), n, infile);
  vec.resize(n);

After reading this thread, though, I can only conclude that an
uninitialized_resize method would compromize the safety of vector.
For example, the following would produce undefined behavior:

  std::vector<int> vec;
  vec.unitialized_resize(10);
  vec.resize(100); // Error! might copy unitialized values

In other words, unitialized_resize would leave a vector in
a state where certain otherwise-legal operations would produce
undefined behavior (unless the type is unsigned char).

Again, I suspect the initialization cost is rarely an issue.
Personally, if I want a fixed-size array of static or automatic
duration, I might choose a C-style array. Otherwise, if I want
an array that is dynamic in either duration or size, I use a
vector.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ark@research.att.com (Andrew Koenig)
Date: 1999/11/17
Raw View
In article <80ppte$ipl$1@nnrp1.deja.com>,  <niklasb@my-deja.com> wrote:

>Again, I suspect the initialization cost is rarely an issue.
>Personally, if I want a fixed-size array of static or automatic
>duration, I might choose a C-style array. Otherwise, if I want
>an array that is dynamic in either duration or size, I use a
>vector.

Why not use std::allocator<int> directly?
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW <allan_w@my-deja.com>
Date: 1999/11/17
Raw View
In article <80b5m1$a6t$1@nnrp1.deja.com>,
  fleye@my-deja.com wrote:
> In article <m3nV3.3465$x12.141442@ndnws01.ne.mediaone.net>,
>   "Dave Abrahams" <abrahams@mediaone.net> wrote:
> > In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> > smeyers@aristeia.com (Scott Meyers) wrote:
> >
> > > Is there any way to create a vector (or other standard
> > > container) of built-in types without paying for zero-
> > > initialization of the data in the container?
> >
> > No, but if you can live with a container of wrapped
> > built-in types, you can get almost the same thing:
> >
> > struct Int { int x; }
> > vector<Int> v(20);
>
> The compiler generated copy ctor will still be called n times
> plus one default ctor call, which may be optimized away.

Meaning that the default ctor call could be optimized away, but
not the copy ctor.

> struct Int {
>   Int() {}
>   explicit Int(const Int&) {}
>   int x;
> };
>
> is more like it, assuming you have a optimizing compiler that
> can optimize away the uninitialized_fill_n call.
> But this Int is kinda dangerous if you are not careful...

Dangerous? This is useless. You can't copy a value out of the
vector! Vector elements must be CopyConstructable. Your
compiler has no idea that the copy constructor that you just
defined actually AVOIDS the construction. It doesn't have two
different copy constructors, and if it did it wouldn't know
which one to use.

The net result: WHENEVER you need to copy an element, you
actually create an uninitialized copy! For instance, whenever
the vector needs to change size, it copy-constructs all of
the elements and then destroys the old ones. Since your copy
constructor does nothing, you end up with every element in
the vector suddenly un-initializing itself!

I suppose you could get around it like this:
    struct Int {
    private:
      static bool able;
    public:
      int x;
      static void disable() { able = false; }
      static void enable() { able = true; }
      Int() { if (able) x=0; }
      explicit Int(const Int&that) { if (able) x=that.x; }
    };
    bool Int::able = true;

and then use it this way:

    Int::disable();
    vector<Int> x(100);
    Int::enable();

Since Int() has been re-enabled, the copies will work. But
the catch here is that the code to check if the copy should
take place will actually take longer than the copy would have
taken if we hadn't bothered to check!

> Fly.

I always try to...

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/17
Raw View
In article <memo.19991113150030.42053A@btinternet.com>,
  brangdon@cix.co.uk wrote:

> andrewalex@hotmail.com (Andrei Alexandrescu) wrote:
> > Imagine you advocate using STL in an organization.
> > [...]
> > "You're saying we should use something that we have to patch from
day
> > one???"

> This is agreeing with my comment, "Perhaps something like this should
> have been included in the std library". If it had been, the
> organisation would not have had to patch it in themselves.

Any time you have special demands, you will have to write special code.
I'm sure in my career that I've seen at least twenty special cases where
vector wouldn't have been acceptable -- do you really think that the
standard needs twenty additional vector classes, just to meet my special
one-time needs?

(I'm not arguing for or against an on-stack vector in the standard.  I
am arguing that the simple fact that one application happens to need
something other than vector is *not* a sufficient argument to add that
something to the standard library.)

> That said, I really wonder whether the STL is right for these
> people. I'm not religious about it. The main advantage of vector<>
> over C arrays is in the memory management. I sort-of expect most
> arrays would benefit from the flexibility, and the few places that
> don't would benefit from conforming to the protocol used in the places
> that do. If nowhere benefits, then why make the switch?

The main benefit is that vector stays a vector, where as the built-in
arrays have a nasty habit of turning into pointers at the most awkward
moments.  Another nice feature is that the vector has a size -- so does
a built-in array, until it turns into a pointer.

> Let's not forget that a C point is an iterator and the algorithms work
> with C arrays. You don't have to adopt std::vector to benefit from the
> STL.

Correct.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/17
Raw View
In article <r5bPyBAEyKL4EwmZ@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:

> In article <80gqk6$evl$1@nnrp1.deja.com>,
James.Kanze@dresdner-bank.com
> writes
> >> But any read access will have undefined behaviour, and copying
> >> implicitly requires reading.  OK, in practice a POD can be copied
> >> with memcpy() and that should not exhibit undefined behaviour (I
> >> think).

> >But the initialization in vector is guarantied *not* to use memcpy
> >(except in the case where a conforming program cannot tell the
> >difference).

> Really?  Well that would be news to many responsible for providing
> default copy ctors for PODs which are often implemented in exactly
> that way.

The standard requires correct copy semantics for any type in vector.  In
other words, an implementation must use the equivalent of the STL
uninitialized_fill, and *not* memcpy.

Of course, anytime a conforming program cannot tell...  If the
implementation has a trick by which it can recognize that certain types
can be initialized by memcpy, with the same results, and only uses
memcpy for those types, fine.  That's what the as if rule is for.  But
if my program can tell that memcpy has been used, then the
implementation is not conforming.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/18
Raw View
In article <80c29a$urc$1@nnrp1.deja.com>,
  wmm@fastdial.net wrote:
>
> In article <MPG.128c1ac763b096ca9896ef@news.teleport.com>,
>   smeyers@aristeia.com (Scott Meyers) wrote:

> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data in
> > the container?

> >   {A related question was discussed in the core language working
> >   group at the standards meeting last week. Perhaps someone from CWG
> >   would respond... Andy Koenig in particular knows the latest
> >   status. -hps}

> The rest of this thread, I think, has sufficiently answered Scott's
> original question (bottom line, no, there's no way to get a POD type
> to exhibit the behavior he wants; the only way to do it is to create
> a non-POD type as a wrapper).

I think that the bottom line was rather that creating a non-POD type as
a wrapper 1) didn't really help, because the initialization copy loop
would be executed anyway, and 2) that it resulted in undefined behavior,
since copying the uninitialized objects in the non-POD type was
undefined behavior.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/18
Raw View
James.Kanze@dresdner-bank.com () wrote:
> (I'm not arguing for or against an on-stack vector in the standard.  I
> am arguing that the simple fact that one application happens to need
> something other than vector is *not* a sufficient argument to add that
> something to the standard library.)

Agreed. I felt this particular collection had strong arguments in its
favour, as a matter of completeness and of easing the transition. A matter
of reaching down to C rather than up to an unbounded sky. I also felt it
would be relatively easy to get agreement, compared to, say, a hash map.

On the other hand, if it's just a transition tool it probably doesn't
deserve to be in a long-lived standard. And I confess I have implemented
my own version of it which is a little bit quirky (it's indexed by enums
for better type-checking), so perhaps a standard form wouldn't be so
useful.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/11/15
Raw View
In article <s2mtivughsq93@news.supernews.com>,
Andrei Alexandrescu <andrewalex@hotmail.com> wrote:

>That's really astonishing news. Does this apply to C, too? Does the
>following C program engender undefined behavior?

>int main()
>{
>    double d;
>    d = 9;
>    return 0;
>}

To set the matter straight, I thought I was reading a claim that
it was possible to assign a previously uninitialized value, not
to assign *to* such a variable.

Your example above is just fine.  What's undefined is

 int main()
 {
  double d, e;
  e = d;  /* might crash, either in C or C++ */
  return 0;
 }
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: wmm@fastdial.net
Date: 1999/11/16
Raw View
In article <MPG.128c1ac763b096ca9896ef@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:
>
> Is there any way to create a vector (or other standard container) of
> built-in types without paying for zero-initialization of the data in
the
> container?
>
>   {A related question was discussed in the core language working group
>   at the standards meeting last week. Perhaps someone from CWG would
>   respond... Andy Koenig in particular knows the latest status. -hps}

The rest of this thread, I think, has sufficiently answered Scott's
original question (bottom line, no, there's no way to get a POD type
to exhibit the behavior he wants; the only way to do it is to create
a non-POD type as a wrapper).  However, I did want to clear up Herb's
comment about the discussion at the J16/WG21 meeting last month.

A bit of background: acting on a suggestion by Andy Koenig, the
Committee in April tentatively accepted a proposal to define something
called "value initialization."  (By "tentatively accepted," I mean
that the current intent of the Committee is to include the change in
the first Technical Corrigendum to the Standard, although that intent
is subject to reconsideration up to the point that the TC is actually
approved.)  The problem is that the definition of "default
initialization," which in the current Standard applies to expressions
like "T()," produces undefined behavior when a) "T" is a class type
with POD members and a non-trivial compiler-generated default
constructor, and b) the value of "T()" is copied, which is really
about the only useful thing you can do with such an expression.

The reason for the undefined behavior is that the definition of
"default initialization" for a non-POD type is simply to call the
default constructor; the compiler-generated default constructor will
(correctly and appropriately) leave POD members of the class
uninitialized, and copying an uninitialized value (as a member of the
class) results in undefined behavior.

The solution was to define "value initialization", which applies in
exactly this case: a class type with no user-defined constructor.  In
"value initialization," members with constructors have their
constructors called and members of POD type are zero-initialized.  In
the April, 1999 resolution, "value initialization" was applied only
to explicit temporary expressions (expressions of the form "T()").
(I've omitted a couple of subtleties here; see issue #35 in the core
issues list for the exact text of the change.)

In the interim, we realized that there are actually three contexts in
which an initializer is specified as "()": explicit temporaries, in
a new-initializer, and in a mem-initializer.  We covered the first one
in April, and we had earlier discussed the second and explicitly
decided not to apply value initialization to it.  However, the third
context was one we had overlooked, and it seemed desirable to apply
value initialization to it.  Given that two of the three cases of "()"
as an initializer should be value initialization, it seemed too
inconsistent to have "new T()" do default initialization, so we
reconsidered our earlier decision there, too.  (If you want to get
default initialization, you can by simply omitting the initializer,
i.e., "new T" instead of "new T()".)

There was informal consensus that this was the correct approach, and
Andy Koenig has written up a detailed proposal for implementing this
more-complete application of value initialization which we expect to
consider formally at the April, 2000 meeting.

So the discussion last month was slightly related to the topic here,
but didn't address Scott's question directly.
--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)


Sent via Deja.com http://www.deja.com/
Before you buy.


      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/16
Raw View
In article <MPG.128c1ac763b096ca9896ef@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:

> Suppose I want a dynamically allocated array of n integers of
> indeterminate value.  I can get one like this:

>   int *someInts = new int[n];

> Further suppose I prefer vectors or deques to arrays.  I could do

>   vector<int> someInts(n);

> but each int in the vector would be initialized to 0.  I may not want
> to pay for that.  I could try this,

>   vector<int> someInts;
>   someInts.reserve(n);

> but even if it were safe to index into someInts (e.g., someInts[i]) to
> get random bits (such indexing would, I suspect, yield undefined
> results), someInts.size() would always be wrong.

And you are right in thinking that such indexing would yield undefined
behavior.

> Is there any way to create a vector (or other standard container) of
> built-in types without paying for zero-initialization of the data in
> the container?

You never have zero-initialization of any of the data in the container.
You have copy initialization.  Which means that finding a way of getting
around the zero-initialization in T() won't help much -- you'll still
pay for the initialization, but without any of the advantages of it.

About the closest you can come is to initialize with push_back after the
reserve, although this only works if you initialize in order, and still
has the overhead of changing the logical size at each insertion.

Might I remind you, however, that vector always uses dynamic memory.  On
the machines I'm familiar with, the cost of allocation is far greater
than the cost of the initialization anyway.  If speed (of construction)
is a concern, I can think of two possible solutions:

  - Use a pool of already created vectors, cycling the new ones out of a
    free list.

  - write your own vector class -- I think Herb Sutter once posted a
    static_vector class along the lines of what I am thinking about.
    Basically, if the size of the vector is one of the template
    parameters, you can avoid the dynamic allocation entirely, which
    will typically save more time than avoiding the initialization.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Linda Sherman <linsherm@gte.net>
Date: 1999/11/16
Raw View


Scott Meyers wrote:
>
> Is there any way to create a vector (or other standard container) of
> built-in types without paying for zero-initialization of the data in the
> container?

My first thought would be to write my own allocator class. I would think
you'd want to anyway - if you can't afford to pay for initialization
there may be other things the necessarily generic standard allocator is
doing that you don't want to pay for either.

Lin
linsherm@gte.net



      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/11/16
Raw View
James Kanze <James.Kanze@dresdner-bank.com> wrote:
> I think that x = y is undefined behavior if y is not initialized,
> and has a type other than char or unsigned char.  In which case, you
> have the undefined behavior that Valentin was talking about.

Darin Adler <darin@bentspoon.com> asked:
> Is there wording to this effect?

And James Kanze answered:
> I think so, but I'm not sure where to look for it.

Once you realize that a C++ implementation doesn't read variables,
but instead converts lvalues to rvalues, it's easy to find.  It's
4.1 [conv.lval], paragraph 1:

     An lvalue (3.10) of a non-function, non-array type T can be
     converted to an rvalue. [...] If the object to which the lvalue
     refers is not an object of type T and is not an object of a type
     derived from T, or if the object is uninitialized, a program
     that necessitates this conversion has undefined behavior.

                                                --Lisa Lippincott


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/11/12
Raw View
On 11 Nov 1999 21:02:43 GMT, James Kuyper Jr. wrote:
> Call v.reserve() to do the equivalent of new[], then call v.push_back()
> or v.insert(end(),) when you can actually generate the initializing
> values. This should have pretty close to the same efficiency as what
> you'd like.

Perhaps.  I'd expect a test of size against capacity for each insertion.
If n is big, that's a lot of tests.

FWIW, this posting (to clcm) is what got me interested in this whole
matter:

  Subject: vector vs array
  Date: 1999/08/09
  Author: Jak Kirman <jak@hayley.cs.brown.edu>

  Is it reasonable to assert that one should *always* use vectors rather
  than arrays?

  If I am implementing a 26-way tree to store a dictionary, for example,
  and I know that porting to a different natural language will require a
  complete redesign of this portion of my program, it seems reasonable to
  me to use an array of 26 pointers rather than a vector of the same.

  In one particular application where I tried the two, I found that loading
  the dictionary took about 50% longer with vectors than arrays, even
  though I was specifying the size of the vector at creation time.

  Are there any significant reasons for preferring to use vector over plain
  arrays despite this performance degradation?

This suggests that for at least one combination of application, compiler,
and library implemenation, use of vector<T*> is significantly slower than
use of T[n].  This is hardly conclusive, of course, because my guess is
that his array implementation was on the stack and a vector's data is on
the heap, but still, it makes one wonder.  Or at least it makes me wonder.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/12
Raw View
In article <wNlJfeA5uuK4EwvX@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> In article <s2jf1ij7hsq81@news.supernews.com>, Andrei Alexandrescu
> <andrewalex@hotmail.com> writes

> >He doesn't want undefined behavior. It's certainly about defined
> >behavior.  The initial values of the integers are undefined, not the
> >behavior.

> But any read access will have undefined behaviour, and copying
> implicitly requires reading.  OK, in practice a POD can be copied with
> memcpy() and that should not exhibit undefined behaviour (I think).

But the initialization in vector is guarantied *not* to use memcpy
(except in the case where a conforming program cannot tell the
difference).

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/12
Raw View
In article <TWUxJaA9M1K4EwbE@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>
> In article <FL1LJy.A86@research.att.com>, Andrew Koenig
> <ark@research.att.com> writes
> >>I think we need to remember the original question here.  It has to do with
> >>vectors of *built-in type*.  I hope we can agree that one of the things you
> >>can safely do with uninitialized objects of built-in type is assign to
                                             ^^
> I think that little word is rather critical.

I think that Andy realized this.

> >>them.

> >Heck, no!

> >The only built-in type whose undefined values are guaranteed by
> >the C++ standard to be safely assignable is unsigned char.

The critical word is "values".  You can assign *to* an uninitialized
variable.  But you cannot use its value in an assignment.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: hinnant@anti-spam_metrowerks.com (Howard Hinnant)
Date: 1999/11/12
Raw View
In article <382B90FD.F676FC7@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:

> Howard Hinnant wrote:
> > I'm going to chicken out and tackle only your first example.  Thinking
> > about something like this (which admittedly is proably abusing the system,
> > and definitely a pain in the rear):
>
> You're overdoing it

Agreed.

> - that's the easy case.

Yup, admitted that up front.

> With a decent
> implementation:
>
>         std::vector<int> v();
>         v.reserve(10);
>         for(int i=0; i<10; i++)
>                 v.push_back(i);
>
> should do the job.

Not quite as efficient as what I wrote.  The iterator constructor doesn't
have to keep checking internals after every "push_back".  Note that this
is true only if the iterator is not limited to being an input iterator,
which is why I hacked it up as a random access type.

But actually I think the answer below is the best one:

In article <80f3ot$7ik$1@nnrp1.deja.com>, fleye@my-deja.com wrote:

> Also it's easy to write your own vector class and
> have the behaviors you wanted (and add bound checks for debugging
> purpose, static buffer to eliminate heap allocation etc.). And all the
> wonderful STL algorithms can still be used with your own vector. vector
> is the simplest container in STL. I suggest every C++ programmer
> implement an STL like vector at least once -- it's not that hard, and
> it's fun.

-Howard


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/12
Raw View
Scott Meyers <smeyers@aristeia.com> wrote in message
news:MPG.12954f55bd8638199896f6@news.teleport.com...
> On 11 Nov 1999 21:02:43 GMT, James Kuyper Jr. wrote:
> > Call v.reserve() to do the equivalent of new[], then call v.push_back()
> > or v.insert(end(),) when you can actually generate the initializing
> > values. This should have pretty close to the same efficiency as what
> > you'd like.
>
> Perhaps.  I'd expect a test of size against capacity for each insertion.
> If n is big, that's a lot of tests.

I guess this disadvantage goes away if you call insert for ranges. Like:

vector<double> v;
v.resize(n);
v.insert(v.end(), from, to);

Now from and to have to be input iterators. If you really want to be
efficient, you have to design an iterator that does what you want (like
calling a function). Anyway, in the end you get the whole thing as fast as a
for loop.

Seems like a long and winding road...


Andrei



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/11/12
Raw View
In article <TWUxJaA9M1K4EwbE@robinton.demon.co.uk>,
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:

>In article <FL1LJy.A86@research.att.com>, Andrew Koenig
><ark@research.att.com> writes
>>>I think we need to remember the original question here.  It has to do with
>>>vectors of *built-in type*.  I hope we can agree that one of the things you
>>>can safely do with uninitialized objects of built-in type is assign to

>I think that little word is rather critical.

Indeed.  I wonder if my screen width was such that it scrolled to
the next line, because I clearly remember reading "assign them."

Anyway, I agree with the statement above -- you most certainly can
assign a value to an object of built-in type that hasn't yet been
initialized.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/12
Raw View
smeyers@aristeia.com (Scott Meyers) wrote:
> This suggests that for at least one combination of application,
> compiler, and library implemenation, use of vector<T*> is
> significantly slower than use of T[n].  This is hardly conclusive,
> of course, because my guess is that his array implementation was on
> the stack and a vector's data is on the heap, but still, it makes
> one wonder.  Or at least it makes me wonder.

Hopefully implementations will get faster as they mature.

Meanwhile, if you really care about this stuff you can write your own
collection. It's not hard to get the theoretical efficiency of a built-in
array with the interface of a std::vector. This would encapsulate the
decision of which kind of collection was used, and would make it easy eg
to add range-checking in the DEBUG version.

The code would look vaguely like:

    template <typename T, size_t Size>
    class FixedVector {
    public:
        size_t size() const { return Size; }
        T *begin() { return m_data; }
        T *end() { return m_data+Size; }
        T &operator[]( size_t i ) {
            assert( i < Size );
            return m_data[i];
        }
        //...
    private:
        T m_data[Size];
    };

Or whatever (eg it should be using typedef's instead of (T*) but the
details are obvious). Perhaps something like this should have been
included in the std library, for completeness.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/12
Raw View
Andrei Alexandrescu wrote:

> Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
> news:382705BA.A02@wanadoo.fr...
> [Dave Abraham's code]
> > > struct Int { int x; }
> > > vector<Int> v(20);
> >
> > If that was true, then you would get undefined behaviour.
> > Hopefully it isn't.
>
> If what was true?

If Dave was right.

> > You can still get the undefined behaviour you seem to
> > want with:
>
> He doesn't want undefined behavior.

Are you sure ? Did you asked him ?

> The initial values of the integers are undefined, not the behavior.

Both are undefined.

> >   struct Int { int x; Int () {} };
> >   vector<Int> v(20);
>
> I don't see any difference between this code and Dave Abrahams' (quoted
> above).

Try diff

--

Valentin Bonnard


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/12
Raw View
James Kuyper Jr. wrote:

> Ed Brey wrote:
>
> > <James.Kanze@dresdner-bank.com> wrote in message
> > news:80c39k$vn2$1@nnrp1.deja.com...
> > >
> > > In article <MPG.129139ebf21570899896f1@news.teleport.com>,
> > >   smeyers@aristeia.com (Scott Meyers) wrote:
> > > >
> > > > >   struct Int { int x; Int () {} };
> > > > >   vector<Int> v(20);

> > Isn't a compiler allowed to realize that an undefined value is being copied
> > to each member of the vector and therefore elide the copy? ...

Short answer: yes

Long answer: the behaviour is undefined

> > ... Or is the copy
> > required to ensure that all elements have the same undefined value?
>
> Yes.

Sorry, no

--

Valentin Bonnard


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James.Kanze@dresdner-bank.com
Date: 1999/11/13
Raw View
In article <B44F11EE.8547%darin@bentspoon.com>,
  Darin Adler <darin@bentspoon.com> wrote:
>
> James.Kanze@dresdner-bank.com <James.Kanze@dresdner-bank.com> wrote:

> > I think that x =3D y is undefined behavior if y is not initialized,
> > and has a type other than char or unsigned char.  In which case, you
> > have the undefined behavior that Valentin was talking about.

> The exact wording of the standard is that such a variable has
> "indeterminate initial value". I can't find any wording elsewhere that
> indicates that copying such an indeterminate value would lead to
> undefined behavior in a broader sense.

> Is there wording to this effect?

I think so, but I'm not sure where to look for it.  I do remember having
discussions in the C news groups about this.  If I remember correctly,
the rationale was that it was legal for an int to contain bits which
don't affect its status, that these bits must have particular values,
and that the system could abort if the bits didn't have the particular
values when accessed.  And that unsigned char represented a special
exception, to permit accessing raw memory.

In practice, I've only heard of one machine which had unused bits in its
integer representation.  It also required these bits to be zero, but I
think it just copied them without looking on simple moves.  (Attempting
to add or subtract with an uninitialized int would cause problems on
this machine.)

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient=E9e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/13
Raw View
In article <382B0EB5.80EBA5F8@wizard.net>,
  "James Kuyper Jr." <kuyper@wizard.net> wrote:
> Ed Brey wrote:

> > <James.Kanze@dresdner-bank.com> wrote in message
> > news:80c39k$vn2$1@nnrp1.deja.com...

> > > In article <MPG.129139ebf21570899896f1@news.teleport.com>,
> > >   smeyers@aristeia.com (Scott Meyers) wrote:

> > > > >   struct Int { int x; Int () {} };
> > > > >   vector<Int> v(20);
> ....
> > Isn't a compiler allowed to realize that an undefined value is being
> > copied to each member of the vector and therefore elide the copy?
> > ...

> No.

I think it would be legal, but I'd be surprised if any compiler did it.

> > ... Or is the copy
> > required to ensure that all elements have the same undefined value?

> Yes.

*Accessing* an uninitialized int other than as raw memory (through a
char* or an unsigned char*) is undefined behavior. Vector does not use
memcpy to copy. Calling the constructor with an uninitialized int is
thus undefined behavior. A compiler is free to *define* undefined
behavior in anyway it wishes.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/13
Raw View
In article <382B90FD.F676FC7@wizard.net>,
  "James Kuyper Jr." <kuyper@wizard.net> wrote:
> Howard Hinnant wrote:
> >
> > In article <382B3AAD.76E5190C@wizard.net>, "James Kuyper Jr."
> > <kuyper@wizard.net> wrote:
> >
> > > What is being discussed here is the desire to have some way to use
> > > vector<> in an efficient substitute for code such as:
> > >
> > >         int *square = new int[10];
> > >         for(int i=0; i<10; i++)
> > >                 square[i] = i*i;
> ....

> > I'm going to chicken out and tackle only your first example.
Thinking
> > about something like this (which admittedly is proably abusing the
system,
> > and definitely a pain in the rear):

> You're overdoing it - that's the easy case. With a decent
> implementation:

>  std::vector<int> v();
>  v.reserve(10);
>  for(int i=0; i<10; i++)
>   v.push_back(i);

You mean: v.push_back( i*i )

> should do the job.

Not really.  Although whether the actual difference is measurable in a
specific implementation or not is an open question, I would expect that
at least on some systems, with a simple expression like i*i, the
difference could be a factor of 2.  In addition to the assignment,
push_back must increment the final position, and test whether it is
beyond the end.  Although we know that because of the reserve, it will
never be beyond the end, it would be an exceptionally good compiler
which could figure this out and optimize away the test.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/13
Raw View
In article <s2kcfvfrhsq37@news.supernews.com>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
>
> <James.Kanze@dresdner-bank.com> wrote in message
> news:80c39k$vn2$1@nnrp1.deja.com...
> > I'm not too sure just what you can do with an uninitialized variable
> > according to the standard.  In practice, you will be able to copy
> > it, even with tools like Purify working.  (I think that x = y is
> > undefined behavior if y is not initialized, and has a type other
> > than char or unsigned char.  In which case, you have the undefined
> > behavior that Valentin was talking about.)

> Couldn't you even assign something to it? It means this code sports
> undefined behavior:

> int main()
> {
>     int x;
>     x = 0;
> }

In C, you are not allowed to access a variable before it has been
initialized.  A POD can be "initialized" either with an initializer in
the definition OR an assignment later in the program.  Before this
initialization, any access is illegal (except for unsigned char and
char).

> I guess that's not the case, so I'm afraid you're wrong. Or I
> misunderstood your question.

You misunderstood what I said.

> > As for legitimate reasons for doing this, it will save the time
> > necessary to initialize a single instance, regardless of the size of
> > the array.  And no more: all of the elements of the vector will
> > still be "initialized" by copying the undefined value into them.  I
> > find it hard to imagine a case where saving the initialization of a
> > single int could be significant.

> Right. It means vector has a problem: building a vector of n integers
> that are going to be filled with some values is inherently slower than
> allocating an array of n integers using new[].

> Basically the question is pretty clear, and I don't understand the
> reason of all these logical push-ups that followed it: is there a way
> one can initialize a vector of primitive types similarly to creating
> an array with operator new[]?

> Unfortunately, it seems that the answer is no.

Correct.  If the initialization is in order, and all of the information
is at hand, you can create a custom iterator which should do the trick.
Otherwise, I suspect that you're stuck.  But as someone else pointed
out, writing your own vector-compatible class which does what you want
isn't that difficult -- perhaps even easier than writing the custom
iterator.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/13
Raw View
Dave Harris <scorp@btinternet.com> wrote in message
news:memo.19991112162219.14597D@btinternet.com...
> Meanwhile, if you really care about this stuff you can write your own
> collection.

Other posters have also suggested rolling your own vector.

Sounds reasonable. However, there is a problem. Imagine you advocate using
STL in an organization.

"Let's use vector<> instead of C arrays."
"What advantages they have?"
"Yadda-yadda-yadda."
"Awesome, but we don't need many of these in project X. We need to allocate
a lot of ints here as fast as possible. Does vector do that?"
"Well, you see, if you want no initialization overhead at all, you must roll
your own vector-like vector." (sic)
"You're saying we should use something that we have to patch from day
one???"


Andrei
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: acurio@my-deja.com
Date: 1999/11/13
Raw View
In article <s2o9ah1ghsq53@news.supernews.com>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
>
> Scott Meyers <smeyers@aristeia.com> wrote in message
> news:MPG.12954f55bd8638199896f6@news.teleport.com...
> > On 11 Nov 1999 21:02:43 GMT, James Kuyper Jr. wrote:
> > > Call v.reserve() to do the equivalent of new[], then call
v.push_back()
> > > or v.insert(end(),) when you can actually generate the
initializing
> > > values. This should have pretty close to the same efficiency as
what
> > > you'd like.
> >
> > Perhaps.  I'd expect a test of size against capacity for each
insertion.
> > If n is big, that's a lot of tests.
>
> I guess this disadvantage goes away if you call insert for ranges.
Like:
>
> vector<double> v;
> v.resize(n);

should be v.reserve(n); otherwise you end up with n 0.s in v before
your inserted stuff.

> v.insert(v.end(), from, to);
>
> Now from and to have to be input iterators. If you really want to be
> efficient, you have to design an iterator that does what you want
(like
> calling a function). Anyway, in the end you get the whole thing as
fast as a
> for loop.

It's interesting to note that a lot people I talked to thought iterator
is some mysterious creature that you have to design/write to take
advantage of STL. Once I show them that you can sort(array, array+n);
they jump on the wagon immediately. iterator is an abstraction of
pointer.

so if just copy from an array:

just use v.insert(v.end(), array, array + n);

This is actually more efficient than the conventional:

for (int i = 0; i < n; ++i) copy[i] = array[i];

As you saved narray addition ops (in [] operator).
Of course real C programmer would always use:

for (double *from = array, *to = copy, *end = from + n; from != end;
++from, ++to) *to = *from;

which is, I guess, where Alex got his iterator idea from.

Fly.



Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Tom Payne <thp@roam-thp2.cs.ucr.edu>
Date: 1999/11/13
Raw View
Scott Meyers <smeyers@aristeia.com> wrote:
[...]
> I hope we can agree that one of the things you
> can safely do with uninitialized objects of built-in type is assign to
> them.  So this yields well-defined results (and is, in addition, not an
> unreasonable thing to want to do):

>   int f(int);           // some function

>   int *p = new int[n];
>   for (int i = 0; i < n; ++i) p[i] = f(i);

> My original question was whether we can replace this with the following and
> pay no overhead for initializing the contents of the vector:

>   vector<int> v(n);   // I want *no initialization overhead* here
>   for (int i = 0; i < n; ++i) p[i] = f(i);

AFIK, the as-if rule allows the implementation to omit that
initialization when such that optimization will have no effect on
behavior.  In the case at hand, that is obvious to us, but not to
implementations compile libraries separately from the their clients.
And, in general, there is no way for a compiler to know that a certain
variable will be initialized before its value gets read.  In fact,
this could be an instance where for STL to be as efficient as
C-style data structures, it requires a mechanism to allow a program to
explicitly suppress initialization.

Tom Payne
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/13
Raw View
<acurio@my-deja.com> wrote in message
news:80hnsr$4qa$1@nnrp1.deja.com...
> > vector<double> v;
> > v.resize(n);
>
> should be v.reserve(n); otherwise you end up with n 0.s in v before
> your inserted stuff.

Sorry; thanks for pointing this out.

> so if just copy from an array:
>
> just use v.insert(v.end(), array, array + n);

Yeah, but what Scott wants is not to copy from an array to a vector.
This is simple. He wants to initialize each element of the array with
some arbitrary expression, say a function call.


Andrei
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/15
Raw View
In article <80gqk6$evl$1@nnrp1.deja.com>, James.Kanze@dresdner-bank.com
writes
>> But any read access will have undefined behaviour, and copying
>> implicitly requires reading.  OK, in practice a POD can be copied with
>> memcpy() and that should not exhibit undefined behaviour (I think).
>
>But the initialization in vector is guarantied *not* to use memcpy
>(except in the case where a conforming program cannot tell the
>difference).

Really?  Well that would be news to many responsible for providing
default copy ctors for PODs which are often implemented in exactly that
way.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/11/15
Raw View
Valentin Bonnard wrote:
>
> Andrei Alexandrescu wrote:
>
> > Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
> > news:382705BA.A02@wanadoo.fr...
...
> > > You can still get the undefined behaviour you seem to
> > > want with:
> >
> > He doesn't want undefined behavior.
>
> Are you sure ? Did you asked him ?

Don't be ridiculous. Scott Meyers definitely didn't want undefined
behavior. He wanted a way to use a vector<> to store a large array
without being forced to initialize all of its values before he was ready
to initialize them.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/15
Raw View
Dave Harris <scorp@btinternet.com> wrote in message
news:memo.19991112162219.14597D@btinternet.com...
> Meanwhile, if you really care about this stuff you can write your
own
> collection. It's not hard to get the theoretical efficiency of a
built-in
> array with the interface of a std::vector.
[short snip]
> The code would look vaguely like:
>
>     template <typename T, size_t Size>
>     class FixedVector {
[snip]

I'm afraid that's not a vector-compatible interface because it doesn't
take the same template parameters. This would prevent usdage with
template template parameters and such scary things.

An implementation that would work is:

template <size_t Size>
class array
{
public:
    template <class T, class Allocator = std::allocator<T> >
    class of
    {
        // here's the meat
    };
};

Then you use it like this:

array<20>::of<int> myArray;

'array<20>::of' behaves the same as 'std::vector'.


Andrei




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/15
Raw View
James.Kanze@dresdner-bank.com wrote:
>
> In article <B44F11EE.8547%darin@bentspoon.com>,
>   Darin Adler <darin@bentspoon.com> wrote:
> >
> > James.Kanze@dresdner-bank.com <James.Kanze@dresdner-bank.com> wrote:
>
> > > I think that x = y is undefined behavior if y is not initialized,
> > > and has a type other than char or unsigned char.  In which case, you
> > > have the undefined behavior that Valentin was talking about.
>
> > The exact wording of the standard is that such a variable has
> > "indeterminate initial value". I can't find any wording elsewhere that
> > indicates that copying such an indeterminate value would lead to
> > undefined behavior in a broader sense.
>
> > Is there wording to this effect?
>
> I think so, but I'm not sure where to look for it.  I do remember having
> discussions in the C news groups about this.  If I remember correctly,
> the rationale was that it was legal for an int to contain bits which
> don't affect its status, that these bits must have particular values,
> and that the system could abort if the bits didn't have the particular
> values when accessed.  And that unsigned char represented a special
> exception, to permit accessing raw memory.

True - section 6.2.6.1 p5 of the C99 standard says:
"Certain object representations need not represent a value of the object
type. If the stored value of an object has such a representation and is
accessed by an lvalue expression that does not have character type, the
behavior is undefined. If such a representation is produced by a side
effect that modifies all or any part of the object by an lvalue
expression that does not have character type, the behavior is
undefined.37) Such a
representation is called a trap representation.

37) Thus, an automatic variable can be initialized to a trap
representation without causing undefined behavior, but the value of the
variable cannot be used until a proper value is stored in it."

There's no comparable wording in the C++ standard. On the other hand,
these words were added against opposition from people who claimed that
they were redundant - that they merely clarified something already
implied by other words in the standard. If their arguments (which were
rejected) were valid, they probably should apply equally well to the C++
standard.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/11/15
Raw View
andrewalex@hotmail.com (Andrei Alexandrescu) wrote:
> Imagine you advocate using STL in an organization.
> [...]
> "You're saying we should use something that we have to patch from day
> one???"

This is agreeing with my comment, "Perhaps something like this should have
been included in the std library". If it had been, the organisation would
not have had to patch it in themselves.

That said, I really wonder whether the STL is right for these people. I'm
not religious about it. The main advantage of vector<> over C arrays is
in the memory management. I sort-of expect most arrays would benefit from
the flexibility, and the few places that don't would benefit from
conforming to the protocol used in the places that do. If nowhere
benefits, then why make the switch?

Let's not forget that a C point is an iterator and the algorithms work
with C arrays. You don't have to adopt std::vector to benefit from the
STL.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/15
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:FL3D6L.9u4@research.att.com...
[actual discussion snipped, just want to joke on a nice typo]

> What's interesting is that if we change "int" to "unsigned char"
> here, the claim becomes true, because there is a guarantee that
> unsighed char values have a 1-1 correspondence with the contents of
> the underlying memory.

I suggest a language change: let's rename "unsighed char" to "relieved
char".


Andrei :o)




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/11
Raw View
<James.Kanze@dresdner-bank.com> wrote in message
news:80c39k$vn2$1@nnrp1.deja.com...
> I'm not too sure just what you can do with an uninitialized variable
> according to the standard.  In practice, you will be able to copy it,
> even with tools like Purify working.  (I think that x = y is undefined
> behavior if y is not initialized, and has a type other than char or
> unsigned char.  In which case, you have the undefined behavior that
> Valentin was talking about.)

Couldn't you even assign something to it? It means this code sports
undefined behavior:

int main()
{
    int x;
    x = 0;
}

I guess that's not the case, so I'm afraid you're wrong. Or I
misunderstood your question.

> As for legitimate reasons for doing this, it will save the time
> necessary to initialize a single instance, regardless of the size of
the
> array.  And no more: all of the elements of the vector will still be
> "initialized" by copying the undefined value into them.  I find it
hard
> to imagine a case where saving the initialization of a single int
could
> be significant.

Right. It means vector has a problem: building a vector of n integers
that are going to be filled with some values is inherently slower than
allocating an array of n integers using new[].

Basically the question is pretty clear, and I don't understand the
reason of all these logical push-ups that followed it: is there a way
one can initialize a vector of primitive types similarly to creating
an array with operator new[]?

Unfortunately, it seems that the answer is no.


Andrei



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/11/11
Raw View
In article <MPG.129398a3d7237ff89896f3@news.teleport.com>,
Scott Meyers <smeyers@aristeia.com> wrote:

>On 10 Nov 1999 17:30:38 GMT, James.Kanze@dresdner-bank.com wrote:

>> I'm not too sure just what you can do with an uninitialized variable
>> according to the standard.  In practice, you will be able to copy it,

>I think we need to remember the original question here.  It has to do with
>vectors of *built-in type*.  I hope we can agree that one of the things you
>can safely do with uninitialized objects of built-in type is assign to
>them.

Heck, no!

The only built-in type whose undefined values are guaranteed by
the C++ standard to be safely assignable is unsigned char.

Many implementations will crash if you try to assign
an uninitialized object of pointer or floating-point
type that happens to have a particularly unfortunate value.

Most implementations won't crash if you try to assign
an uninitialized int, but they are permitted to do so,
and I've seen implementations that do.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/11
Raw View
Andrei Alexandrescu wrote:
....
> Right. It means vector has a problem: building a vector of n integers
> that are going to be filled with some values is inherently slower than
> allocating an array of n integers using new[].
>
> Basically the question is pretty clear, and I don't understand the
> reason of all these logical push-ups that followed it: is there a way
> one can initialize a vector of primitive types similarly to creating
> an array with operator new[]?
>
> Unfortunately, it seems that the answer is no.

Call v.reserve() to do the equivalent of new[], then call v.push_back()
or v.insert(end(),) when you can actually generate the initializing
values. This should have pretty close to the same efficiency as what
you'd like. This won't work if initializing values can not be generated
in index order, but it should be an acceptable solution in cases where
they can be.

The original poster made some comments that some people interpreted as
meaning that he wanted to read the uninitialized values stored in the
memory set aside by the reserve() call - that would be really odd; if he
did need that functionality, this method wouldn't necessarily work. v[n]
for n>=size() is undefined behavior; the same is true for most of the
other methods you could use to access the values. v.at(n) has defined
behavior for n>=size(), but that doesn't help - it's defined to
throw(out_of_range) under those circumstances.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fleye@my-deja.com
Date: 1999/11/11
Raw View
In article <s2kcfvfrhsq37@news.supernews.com>,
  "Andrei Alexandrescu" <andrewalex@hotmail.com> wrote:
>
> <James.Kanze@dresdner-bank.com> wrote in message
> news:80c39k$vn2$1@nnrp1.deja.com...
> > I'm not too sure just what you can do with an uninitialized variable
> > according to the standard.  In practice, you will be able to copy it,
> > even with tools like Purify working.  (I think that x = y is undefined
> > behavior if y is not initialized, and has a type other than char or
> > unsigned char.  In which case, you have the undefined behavior that
> > Valentin was talking about.)
>
> Couldn't you even assign something to it? It means this code sports
> undefined behavior:
>
> int main()
> {
>     int x;
>     x = 0;
> }
>
> I guess that's not the case, so I'm afraid you're wrong. Or I
> misunderstood your question.

I guess you misunderstood James statement, where he was responding to

struct Int { int x; Int() {} };

because Int::x is uninintialized, it might cause undefined behavior
when vector(size_t n, const T& x = T()) does an uninitialized_fill_n
where the uninitialized x is used to copy construct every new element.

Fly.


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ivan J. Johnson" <ivan66@my-deja.com>
Date: 1999/11/11
Raw View
In article <3826F29D.9B6A4F9B@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> Dave Abrahams wrote:
> >
> > In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> > smeyers@aristeia.com (Scott Meyers) wrote:
> >
> > > Is there any way to create a vector (or other standard container)
of
> > > built-in types without paying for zero-initialization of the data
in the
> > > container?
> >
> > No, but if you can live with a container of wrapped built-in types,
you can
> > get almost the same thing:
> >
> > struct Int { int x; }
> > vector<Int> v(20);
>
> Shouldn't this get zero-initialized, too? (POD!)
>
> However
>
> struct Int { Int() {} int x; };
> std::vector<Int> v(20);
>
> should work.

That doesn't really help much.  It will generate a random garbage
value, then fill the vector with 20 identical copies of the value.

--
Regards,
Ivan J. Johnson     C++ consulting and object-oriented
ijohnson (at)           design in Sacramento, CA
alum (dot) mit (dot) edu


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/11
Raw View
Andrew Koenig wrote:
>
> In article <MPG.129398a3d7237ff89896f3@news.teleport.com>,
> Scott Meyers <smeyers@aristeia.com> wrote:
....
> >I think we need to remember the original question here.  It has to do with
> >vectors of *built-in type*.  I hope we can agree that one of the things you
> >can safely do with uninitialized objects of built-in type is assign to
> >them.
>
> Heck, no!
>
> The only built-in type whose undefined values are guaranteed by
> the C++ standard to be safely assignable is unsigned char.

I think you're confusing assignment to an undefined value with
assignment from an undefined value. The following has always been legal:

 int i;
 i = 10;

What is being discussed here is the desire to have some way to use
vector<> in an efficient substitute for code such as:

 int *square = new int[10];
 for(int i=0; i<10; i++)
  square[i] = i*i;

Or, to make things more difficult, consider how to replace

 int *modsqrt = new long[N];
 for (long i=N-1; i>=0; i--)
  modsqrt[(i*i)%N] = i;

with equivalent code using vector<long>.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ross Smith <ross.s@ihug.co.nz>
Date: 1999/11/11
Raw View
Andrew Koenig wrote:
>
> In article <MPG.129398a3d7237ff89896f3@news.teleport.com>,
> Scott Meyers <smeyers@aristeia.com> wrote:
>
> >I think we need to remember the original question here.  It has to do with
> >vectors of *built-in type*.  I hope we can agree that one of the things you
> >can safely do with uninitialized objects of built-in type is assign to
> >them.
>
> Heck, no!
>
> The only built-in type whose undefined values are guaranteed by
> the C++ standard to be safely assignable is unsigned char.
>
> Many implementations will crash if you try to assign
> an uninitialized object of pointer or floating-point
> type that happens to have a particularly unfortunate value.
>
> Most implementations won't crash if you try to assign
> an uninitialized int, but they are permitted to do so,
> and I've seen implementations that do.

I find this extremely difficult to believe. You're saying that code as
simple and common as "int i; i = 1;" is undefined?

Are you sure you aren't confused about which side of the assignment the
undefined value is on? I'm aware that "int i; int j = i;" is undefined,
but that's not what Scott was talking about.

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
  "There are many technical details that make Linux attractive to the
  sort of people to whom technical details are attractive."   -- Suck


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/12
Raw View
In article <FL1LJy.A86@research.att.com>, Andrew Koenig
<ark@research.att.com> writes
>>I think we need to remember the original question here.  It has to do with
>>vectors of *built-in type*.  I hope we can agree that one of the things you
>>can safely do with uninitialized objects of built-in type is assign to
                                                                      ^^
I think that little word is rather critical.

>>them.
>
>Heck, no!
>
>The only built-in type whose undefined values are guaranteed by
>the C++ standard to be safely assignable is unsigned char.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/12
Raw View
In article <80cf53$f071@interserv.etn.com>, Ed Brey
<brey@afd.mke.etn.com> writes
>Isn't a compiler allowed to realize that an undefined value is being copied
>to each member of the vector and therefore elide the copy?

Of course it is because there is no legal program that could tell the
difference (any attempt to read the stored data will be subject to
undefined behaviour)

>

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: hinnant@anti-spam_metrowerks.com (Howard Hinnant)
Date: 1999/11/12
Raw View
In article <382B3AAD.76E5190C@wizard.net>, "James Kuyper Jr."
<kuyper@wizard.net> wrote:

> What is being discussed here is the desire to have some way to use
> vector<> in an efficient substitute for code such as:
>
>         int *square = new int[10];
>         for(int i=0; i<10; i++)
>                 square[i] = i*i;
>
> Or, to make things more difficult, consider how to replace
>
>         int *modsqrt = new long[N];
>         for (long i=N-1; i>=0; i--)
>                 modsqrt[(i*i)%N] = i;
>
> with equivalent code using vector<long>.

I'm going to chicken out and tackle only your first example.  Thinking
about something like this (which admittedly is proably abusing the system,
and definitely a pain in the rear):

#include <vector>
#include <iterator>

class Init
   : public std::iterator<std::random_access_iterator_tag, int>
{
public:
   Init(int data = 0) : data_(data) {}
   int operator*() const {return data_*data_;}
   Init& operator++() {++data_; return *this;}
   Init  operator++(int) {Init tmp(*this); operator++(); return tmp;}
   Init& operator--() {--data_; return *this;}
   Init  operator--(int) {Init tmp(*this); operator--(); return tmp;}
   Init& operator += (difference_type n) {data_ += n; return *this;}
   Init operator + (difference_type n) const {return Init(*this) += n;}
   Init& operator -= (difference_type n) {data_ -= n; return *this;}
   Init operator - (difference_type n) const {return Init(*this) += n;}
   long operator - (const Init& rhs) const {return difference_type(data_ -
rhs.data_);}
   int operator [] (difference_type i) const {Init tmp(*this); tmp += i;
return *tmp;}
   friend Init operator + (difference_type n, const Init& rhs)
         {return Init(rhs) += n;}
   friend bool operator== (const Init& x, const Init& y)
      {return x.data_ == y.data_;}
   friend bool operator!= (const Init& x, const Init& y)
      {return x.data_ != y.data_;}
   friend bool operator< (const Init& x, const Init& y)
      {return x.data_ < y.data_;}
   friend bool operator<=(const Init& x, const Init& y)
      {return x.data_ <= y.data_;}
   friend bool operator> (const Init& x, const Init& y)
      {return x.data_ > y.data_;}
   friend bool operator>=(const Init& x, const Init& y)
      {return x.data_ >= y.data_;}
private:
   int data_;
};

int main()
{
   std::vector<int> a(Init(0), Init(10));
}

On my system this approaches the desired efficiency.

-Howard


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/12
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:FL1LJy.A86@research.att.com...
> Heck, no!
>
> The only built-in type whose undefined values are guaranteed by
> the C++ standard to be safely assignable is unsigned char.
>
> Many implementations will crash if you try to assign
> an uninitialized object of pointer or floating-point
> type that happens to have a particularly unfortunate value.

That's really astonishing news. Does this apply to C, too? Does the
following C program engender undefined behavior?

int main()
{
    double d;
    d = 9;
    return 0;
}


Andrei



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/12
Raw View
> Call v.reserve() to do the equivalent of new[], then call
v.push_back()
> or v.insert(end(),) when you can actually generate the initializing
> values.

I guess that's the best answer to Scott's question.


Andrei



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/12
Raw View
Howard Hinnant wrote:
>
> In article <382B3AAD.76E5190C@wizard.net>, "James Kuyper Jr."
> <kuyper@wizard.net> wrote:
>
> > What is being discussed here is the desire to have some way to use
> > vector<> in an efficient substitute for code such as:
> >
> >         int *square = new int[10];
> >         for(int i=0; i<10; i++)
> >                 square[i] = i*i;
....
> I'm going to chicken out and tackle only your first example.  Thinking
> about something like this (which admittedly is proably abusing the system,
> and definitely a pain in the rear):

You're overdoing it - that's the easy case. With a decent
implementation:

 std::vector<int> v();
 v.reserve(10);
 for(int i=0; i<10; i++)
  v.push_back(i);

should do the job.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/11/12
Raw View
In article <s2jf1ij7hsq81@news.supernews.com>, Andrei Alexandrescu
<andrewalex@hotmail.com> writes
>He doesn't want undefined behavior. It's certainly about defined behavior.
>The initial values of the integers are undefined, not the behavior.

But any read access will have undefined behaviour, and copying
implicitly requires reading.  OK, in practice a POD can be copied with
memcpy() and that should not exhibit undefined behaviour (I think).


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/12
Raw View
Ed Brey wrote:
>
> <James.Kanze@dresdner-bank.com> wrote in message
> news:80c39k$vn2$1@nnrp1.deja.com...
> >
> > In article <MPG.129139ebf21570899896f1@news.teleport.com>,
> >   smeyers@aristeia.com (Scott Meyers) wrote:
> > >
> > > >   struct Int { int x; Int () {} };
> > > >   vector<Int> v(20);
....
> Isn't a compiler allowed to realize that an undefined value is being copied
> to each member of the vector and therefore elide the copy? ...

No.

> ... Or is the copy
> required to ensure that all elements have the same undefined value?

Yes.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fleye@my-deja.com
Date: 1999/11/12
Raw View
In article <MPG.129398a3d7237ff89896f3@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:
> On 10 Nov 1999 17:30:38 GMT, James.Kanze@dresdner-bank.com wrote:
> > I'm not too sure just what you can do with an uninitialized variable
> > according to the standard.  In practice, you will be able to copy
it,
>
> I think we need to remember the original question here.  It has to do
with
> vectors of *built-in type*.  I hope we can agree that one of the
things you
> can safely do with uninitialized objects of built-in type is assign to
> them.  So this yields well-defined results (and is, in addition, not
an
> unreasonable thing to want to do):
>
>   int f(int);           // some function
>
>   int *p = new int[n];
>   for (int i = 0; i < n; ++i) p[i] = f(i);
>
> My original question was whether we can replace this with the
following and
> pay no overhead for initializing the contents of the vector:
>
>   vector<int> v(n);   // I want *no initialization overhead* here
>   for (int i = 0; i < n; ++i) p[i] = f(i);

How about this:

vector<int> v; v.reserve(n); // no overhead here
for (int i = 0; i < n; ++i) v.push_back(f(i)); // copy ctor only

I know there are other cases like:

for (int i = 0; i < n; ++i) v[j(i)] = f(i);

where you need at least a way to set the size of the vector without
touch every new element, which std vector doesn't have. May be we
should propose a method called uninitialized_resize to be added to
containers to accomodate this special situation.

> > As for legitimate reasons for doing this, it will save the time
> > necessary to initialize a single instance, regardless of the size
of the
> > array.  And no more: all of the elements of the vector will still be
> > "initialized" by copying the undefined value into them.  I find it
hard
>
> And all that unwanted copying is precisely my point: I don't want it,
and I
> don't want to have to pay for it.  If I use an array, I get no
unwanted
> initialization of the array's contents.  With a vector, it seems I
can't
> avoid it.
>
> FWIW, my reason for asking is that I *like* the STL and I'd like to
be able
> to convince more people to use it.  But I can't in good conscience
tell
> people about the benefits of vector without also disclosing that they
must
> pay to initialize the contents of the vector, even if such
initialization
> is unnecessary.  In C, there is malloc and there is calloc, and
callers
> choose the one most appropriate for their needs.  With the STL, it
seems,
> all we have is the moral equivalent of calloc.  If that's the way it
is,
> then fine, that's the way it is, but let's not try to disguise it.
For
> some people, it will make a difference.
>
> I was simply hoping I'd overlooked something and there *was* a way to
> create a vector<int> of size n without initializing the ints in the
> vector.  It seems that there isn't.  Oh well.

See above comment. Also it's easy to write your own vector class and
have the behaviors you wanted (and add bound checks for debugging
purpose, static buffer to eliminate heap allocation etc.). And all the
wonderful STL algorithms can still be used with your own vector. vector
is the simplest container in STL. I suggest every C++ programmer
implement an STL like vector at least once -- it's not that hard, and
it's fun.

IMO, the separation of containers and algorithms with the help of
iterator (the abstraction/generalization of C pointer) and template is
the real beauty of STL.

Fly.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Marco Dalla Gasperina" <marcodg@pacifier.com>
Date: 1999/11/12
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:FL1LJy.A86@research.att.com...
>
> In article <MPG.129398a3d7237ff89896f3@news.teleport.com>,
> Scott Meyers <smeyers@aristeia.com> wrote:
>
> >I think we need to remember the original question here.  It has to do
with
> >vectors of *built-in type*.  I hope we can agree that one of the things
you
> >can safely do with uninitialized objects of built-in type is assign to
> >them.
>
> Heck, no!
>
> The only built-in type whose undefined values are guaranteed by
> the C++ standard to be safely assignable is unsigned char.

I don't think that's what Scott said.  It is legal to
assign *to* an uninitialized value with an initialized one.

>  vector<int> v(n);   // I want *no initialization overhead* here
>  for (int i = 0; i < n; ++i) p[i] = f(i);

could be replaced by:

    vector<int> v;
    v.reserve(n);
    for (int i = 0; i < n; ++i) v.push_back( f(i) );

Althought this would replace the initialization overhead
with some additional overhead in the call to push_back.

marco
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/11/12
Raw View
On 11 Nov 1999 18:26:42 GMT, Andrew Koenig wrote:
> Scott Meyers <smeyers@aristeia.com> wrote:
>
> >vectors of *built-in type*.  I hope we can agree that one of the things you
> >can safely do with uninitialized objects of built-in type is assign to
> >them.
>
> Heck, no!
>
> The only built-in type whose undefined values are guaranteed by
> the C++ standard to be safely assignable is unsigned char.
>
> Many implementations will crash if you try to assign
> an uninitialized object of pointer or floating-point
> type that happens to have a particularly unfortunate value.

I'm talking about assigning *to* an uninitialized object.  What you wrote
suggests that this is not portable:

    int x = 4;
    int *p = new int;    // *p (i.e., the just-allocated int) is
                         // uninitialized

    *p = x;              // assign to (the uninitialized) *p

Are you saying that the standard says that that code exhibits undefined
behavior?  If so, what about this?

  void someFunction()
  {
    int y;               // y is uninitialized
    y = 10;              // assign to (the uninitialized) y
  }

If the behavior of the above is undefined, my guess is that there's nary a
standard-conforming C or C++ program in real use anywhere on the planet.

On the other hand, if you were arguing about whether it is valid to copy
*from* an uninitialized value during an assignment, that's quite a
different issue, and one that's not germane to this thread.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/11/09
Raw View
On 8 Nov 1999 21:33:27 GMT, Valentin Bonnard wrote:
> You can still get the undefined behaviour you seem to
> want with:
>
>   struct Int { int x; Int () {} };
>   vector<Int> v(20);

I see no undefined behavior here, and there are legitimate reasons to want
to avoid initializing objects of built-in type, e.g., the first thing you
want to do is assign to them.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/11/09
Raw View
Dave Abrahams wrote:
>
> In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> smeyers@aristeia.com (Scott Meyers) wrote:
>
> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data in the
> > container?
>
> No, but if you can live with a container of wrapped built-in types, you can
> get almost the same thing:
>
> struct Int { int x; }
> vector<Int> v(20);

Shouldn't this get zero-initialized, too? (POD!)

However

struct Int { Int() {} int x; };
std::vector<Int> v(20);

should work.

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "CH Lin" <e.lin@iname.com>
Date: 1999/11/09
Raw View
Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
> > struct Int { int x; }
> > vector<Int> v(20);
>
> If that was true, then you would get undefined behaviour.
> Hopefully it isn't.

why this is undefined behavior?  The programmer deliberately leave the data
member uninitialized.  As long as he knows what he is doing, I won't expect
anything more surprising than an uninitialized variable.  It's not like a
compiler allows to format his disk just because he didn't initialize the
variable.

>
> You can still get the undefined behaviour you seem to
> want with:
>
>   struct Int { int x; Int () {} };
>   vector<Int> v(20);

Isn't a compiler-generated default constructor just like that?

--
CH Lin --
homepage :  http://pages.prodigy.net/ch.lin/
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/11/09
Raw View
Martin Fabian wrote:
>
> Scott Meyers wrote:
> >
> > Suppose I want a dynamically allocated array of n integers of indeterminate
> > value.  I can get one like this:
> >
> >   int *someInts = new int[n];
> >
> > Further suppose I prefer vectors or deques to arrays.  I could do
> >
> >   vector<int> someInts(n);
> >
> > but each int in the vector would be initialized to 0.
> >
> It would?
> The vector constructor constructs an element constructed by its default
> constructor and then copies it to each location, right? Is then the
> default constructor for an int setting the int to 0?

The vector constructor's default value for the initializer is T().
Section 5.2.3p2 says that "The expression T() ... creates an rvalue ...
whose value is determined by default-initization." Section 8.5 p5 says:
"To _default-initialize_ an object of type T means:
-- if T is a non-POD class type ...
-- if T is an array type ...
-- otherwise, the storage for the object is zero-initialized."

....
> Also, doesn't new call the default constructor for each element in the
> array? If so, why wouldn't this set someInts to all 0's?

Section 5.3.4 p15:
"A _new_expression_ that creates an object of type T initializes that
 object as follows:

 -- if the _new-initializer_ is omitted:

    -- If T is a ... non-POD class type (or array thereof), the object
       is default initialized ...

    -- Otherwise, the object created has an indeterminate value. ..."

....
> Seems very strange behavior to me. Either default construction sets the
> int to 0 or it doesn't. It can't be both ways.

The rules for the built-in types are often inconsistent with the ones
for user-defined types, usually for backwards compatibility with C.

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/11/10
Raw View
In article <MPG.129139ebf21570899896f1@news.teleport.com>,
  smeyers@aristeia.com (Scott Meyers) wrote:
>
> On 8 Nov 1999 21:33:27 GMT, Valentin Bonnard wrote:
> > You can still get the undefined behaviour you seem to
> > want with:

> >   struct Int { int x; Int () {} };
> >   vector<Int> v(20);

> I see no undefined behavior here, and there are legitimate reasons to
> want to avoid initializing objects of built-in type, e.g., the first
> thing you want to do is assign to them.

I'm not too sure just what you can do with an uninitialized variable
according to the standard.  In practice, you will be able to copy it,
even with tools like Purify working.  (I think that x = y is undefined
behavior if y is not initialized, and has a type other than char or
unsigned char.  In which case, you have the undefined behavior that
Valentin was talking about.)

As for legitimate reasons for doing this, it will save the time
necessary to initialize a single instance, regardless of the size of the
array.  And no more: all of the elements of the vector will still be
"initialized" by copying the undefined value into them.  I find it hard
to imagine a case where saving the initialization of a single int could
be significant.

--
James Kanze                    mailto:James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/10
Raw View
Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
news:382705BA.A02@wanadoo.fr...
[Dave Abraham's code]
> > struct Int { int x; }
> > vector<Int> v(20);
>
> If that was true, then you would get undefined behaviour.
> Hopefully it isn't.

If what was true?

> You can still get the undefined behaviour you seem to
> want with:

He doesn't want undefined behavior. It's certainly about defined behavior.
The initial values of the integers are undefined, not the behavior.

>   struct Int { int x; Int () {} };
>   vector<Int> v(20);

I don't see any difference between this code and Dave Abrahams' (quoted
above).


Andrei




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: John Jacobsma <j.jacobsma@cyber-wizard.com>
Date: 1999/11/10
Raw View
Scott Meyers asked:
>
> Is there any way to create a vector (or other standard container) of
> built-in types without paying for zero-initialization of the data in
the
> container?

I think there is, but it's going to involve bad practices and possibly
Knowledge Man Was Not Meant To Know (tm).

First, create your own container, say uninitialized_vector. Use the STL
source as a guide, or subclass it from vector. The difference between
this and std::vector is only that uninitialized_vector doesn't
initialize it's contained objects on creation of the container.

Then, do something like this:

uninitialized_vector<int> uninit(n);
vector<int>& someInts = *reinterpret_cast<vector<int>*>(&uninit);

If the speed of not inititalizing the vector is that critical, this
could be worth the ridicule of your fellow programmers.

ttfn,
John Jacobsma


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Darin Adler <darin@bentspoon.com>
Date: 1999/11/10
Raw View
James.Kanze@dresdner-bank.com <James.Kanze@dresdner-bank.com> wrote:

> I think that x = y is undefined behavior if y is not initialized, and has a
> type other than char or unsigned char.  In which case, you have the undefined
> behavior that Valentin was talking about.

The exact wording of the standard is that such a variable has "indeterminate
initial value". I can't find any wording elsewhere that indicates that
copying such an indeterminate value would lead to undefined behavior in a
broader sense.

Is there wording to this effect?

    -- Darin



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Dag Henriksson <dag.henriksson@quidsoft.se>
Date: 1999/11/10
Raw View


Andrei Alexandrescu wrote:

> Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote in message
> news:382705BA.A02@wanadoo.fr...
> [Dave Abraham's code]
> > > struct Int { int x; }
> > > vector<Int> v(20);
> >

>
> He doesn't want undefined behavior. It's certainly about defined behavior.
> The initial values of the integers are undefined, not the behavior.

Yes the behavior is undefined.
The initialization will initalized the items in the vector with a default
initialized struct Int.
Since the member x doesn't get initialized in the code below the lvalue to
rvalue conversion produces undefined behavior. (see 4.1 / 1)
The code above is OK however.

>
>
> >   struct Int { int x; Int () {} };
> >   vector<Int> v(20);
>
> I don't see any difference between this code and Dave Abrahams' (quoted
> above).

Since Daves struct is a POD, Int() will zero initialize it's members.
Valentins struct is a non-POD and will therefore leave x uninitalized.

-- Dag Henriksson



[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/11/11
Raw View
<James.Kanze@dresdner-bank.com> wrote in message
news:80c39k$vn2$1@nnrp1.deja.com...
>
> In article <MPG.129139ebf21570899896f1@news.teleport.com>,
>   smeyers@aristeia.com (Scott Meyers) wrote:
> >
> > >   struct Int { int x; Int () {} };
> > >   vector<Int> v(20);
[...]
> As for legitimate reasons for doing this, it will save the time
> necessary to initialize a single instance, regardless of the size of the
> array.  And no more: all of the elements of the vector will still be
> "initialized" by copying the undefined value into them.  I find it hard
> to imagine a case where saving the initialization of a single int could
> be significant.

Isn't a compiler allowed to realize that an undefined value is being copied
to each member of the vector and therefore elide the copy?  Or is the copy
required to ensure that all elements have the same undefined value?

In the interest of efficiency, I think it would make sense to allow the
compiler to skip the copying to the array.
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Darin Adler <darin@bentspoon.com>
Date: 1999/11/11
Raw View
["Dave Abraham's code"]
>>> struct Int { int x; }
>>> vector<Int> v(20);

["this code"]
>> struct Int { int x; Int () {} };
>> vector<Int> v(20);

Andrei Alexandrescu <andrewalex@hotmail.com> wrote:
> I don't see any difference between this code and Dave Abrahams' (quoted
> above).

The difference is that "Dave Abraham's code" Int has POD type.

As has been discussed previously in other threads in this newsgroup, default
initialization of a POD-struct results in default initialization of all the
members because of paragraph 8.5/9 in the C++ standard. That means that if
you default-initialize a "Dave Abraham's code" Int then x is also
default-initialized, yielding an initial value of 0.

The "this code" Int does not have POD type, because a constructor is
explicitly defined. Since the constructor does not explicitly initialize the
member x, the other rule from the standard paragraph 8.5/9 applies when
default-initializing a "this code" Int, and x has an indeterminate initial
value.

    -- Darin
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/11/11
Raw View
On 10 Nov 1999 17:30:38 GMT, James.Kanze@dresdner-bank.com wrote:
> I'm not too sure just what you can do with an uninitialized variable
> according to the standard.  In practice, you will be able to copy it,

I think we need to remember the original question here.  It has to do with
vectors of *built-in type*.  I hope we can agree that one of the things you
can safely do with uninitialized objects of built-in type is assign to
them.  So this yields well-defined results (and is, in addition, not an
unreasonable thing to want to do):

  int f(int);           // some function

  int *p = new int[n];
  for (int i = 0; i < n; ++i) p[i] = f(i);

My original question was whether we can replace this with the following and
pay no overhead for initializing the contents of the vector:

  vector<int> v(n);   // I want *no initialization overhead* here
  for (int i = 0; i < n; ++i) p[i] = f(i);

> As for legitimate reasons for doing this, it will save the time
> necessary to initialize a single instance, regardless of the size of the
> array.  And no more: all of the elements of the vector will still be
> "initialized" by copying the undefined value into them.  I find it hard

And all that unwanted copying is precisely my point: I don't want it, and I
don't want to have to pay for it.  If I use an array, I get no unwanted
initialization of the array's contents.  With a vector, it seems I can't
avoid it.

FWIW, my reason for asking is that I *like* the STL and I'd like to be able
to convince more people to use it.  But I can't in good conscience tell
people about the benefits of vector without also disclosing that they must
pay to initialize the contents of the vector, even if such initialization
is unnecessary.  In C, there is malloc and there is calloc, and callers
choose the one most appropriate for their needs.  With the STL, it seems,
all we have is the moral equivalent of calloc.  If that's the way it is,
then fine, that's the way it is, but let's not try to disguise it.  For
some people, it will make a difference.

I was simply hoping I'd overlooked something and there *was* a way to
create a vector<int> of size n without initializing the ints in the
vector.  It seems that there isn't.  Oh well.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fleye@my-deja.com
Date: 1999/11/11
Raw View
In article <m3nV3.3465$x12.141442@ndnws01.ne.mediaone.net>,
  "Dave Abrahams" <abrahams@mediaone.net> wrote:
> In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> smeyers@aristeia.com (Scott Meyers) wrote:
>
> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data
in the
> > container?
>
> No, but if you can live with a container of wrapped built-in types,
you can
> get almost the same thing:
>
> struct Int { int x; }
> vector<Int> v(20);

The compiler generated copy ctor will still be called n times plus one
default ctor call, which may be optimized away.

struct Int {
  Int() {}
  explicit Int(const Int&) {}
  int x;
};

is more like it, assuming you have a optimizing compiler that can
optimize away the uninitialized_fill_n call.

But this Int is kinda dangerous if you are not careful, as Int x(copy)
does nothing (the explicit keyword can catch Int x = copy) which might
be counter intuitive.

Fly.



Sent via Deja.com http://www.deja.com/
Before you buy.

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/11/11
Raw View
Dag Henriksson <dag.henriksson@quidsoft.se> wrote in message
news:3829D761.FC5D91B5@quidsoft.se...
> Since Daves struct is a POD, Int() will zero initialize it's
members.
> Valentins struct is a non-POD and will therefore leave x
uninitalized.

Oh, sorry.


Mea Culpa
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/11/06
Raw View
Suppose I want a dynamically allocated array of n integers of indeterminate
value.  I can get one like this:

  int *someInts = new int[n];

Further suppose I prefer vectors or deques to arrays.  I could do

  vector<int> someInts(n);

but each int in the vector would be initialized to 0.  I may not want to
pay for that.  I could try this,

  vector<int> someInts;
  someInts.reserve(n);

but even if it were safe to index into someInts (e.g., someInts[i]) to get
random bits (such indexing would, I suspect, yield undefined results),
someInts.size() would always be wrong.

Is there any way to create a vector (or other standard container) of
built-in types without paying for zero-initialization of the data in the
container?

  {A related question was discussed in the core language working group
  at the standards meeting last week. Perhaps someone from CWG would
  respond... Andy Koenig in particular knows the latest status. -hps}

Thanks,

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Dave Abrahams" <abrahams@mediaone.net>
Date: 1999/11/08
Raw View
In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
smeyers@aristeia.com (Scott Meyers) wrote:

> Is there any way to create a vector (or other standard container) of
> built-in types without paying for zero-initialization of the data in the
> container?

No, but if you can live with a container of wrapped built-in types, you can
get almost the same thing:

struct Int { int x; }
vector<Int> v(20);
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin Fabian <fabianNOSPAM@s2.chalmers.se>
Date: 1999/11/08
Raw View
Scott Meyers wrote:
>
> Suppose I want a dynamically allocated array of n integers of indeterminate
> value.  I can get one like this:
>
>   int *someInts = new int[n];
>
> Further suppose I prefer vectors or deques to arrays.  I could do
>
>   vector<int> someInts(n);
>
> but each int in the vector would be initialized to 0.
>
It would?
The vector constructor constructs an element constructed by its default
constructor and then copies it to each location, right? Is then the
default constructor for an int setting the int to 0?

class Default
{
public:
    Default()
    {
        std::cout << "Default constructed" << std::endl;
    }
    Default(const Default &)
    {
        std::cout << "Default copied" << std::endl;
    }
};

int main()
{
    Default d1;  // Default construction
    const Default &d2 = Default(); // Default construction + copy

    int i1;  // Default construction???
    const int &i2 = int(); // Default construction!! + copy
}

Also, doesn't new call the default constructor for each element in the
array? If so, why wouldn't this set someInts to all 0's?

Seems very strange behavior to me. Either default construction sets the
int to 0 or it doesn't. It can't be both ways.

>I may not want to pay for that.
>
Definitely.

<snap>
--
Martin Fabian                         http://www.s2.chalmers.se/~fabian/
                                                                      --
"Cheer up. It may never happen"                          (Edina Monsoon)

        /* Remove NOSPAM from reply-to address to mail me */
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/08
Raw View
Dave Abrahams wrote:

> In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> smeyers@aristeia.com (Scott Meyers) wrote:
>
> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data in the
> > container?
>
> No, but if you can live with a container of wrapped built-in types, you can
> get almost the same thing:
>
> struct Int { int x; }
> vector<Int> v(20);

If that was true, then you would get undefined behaviour.
Hopefully it isn't.

You can still get the undefined behaviour you seem to
want with:

  struct Int { int x; Int () {} };
  vector<Int> v(20);

--

Valentin Bonnard

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ivan J. Johnson" <ivan66@my-deja.com>
Date: 1999/11/08
Raw View
In article <m3nV3.3465$x12.141442@ndnws01.ne.mediaone.net>,
  "Dave Abrahams" <abrahams@mediaone.net> wrote:
> In article <MPG.128c1ac763b096ca9896ef@news.teleport.com> ,
> smeyers@aristeia.com (Scott Meyers) wrote:
>
> > Is there any way to create a vector (or other standard container) of
> > built-in types without paying for zero-initialization of the data
in the
> > container?
>
> No, but if you can live with a container of wrapped built-in types,
you can
> get almost the same thing:
>
> struct Int { int x; }
> vector<Int> v(20);

I don't think that will save you from the initialization cost.  Here is
the vector constructor from the sgi STL:

  explicit vector(size_type __n)
    : _Base(__n, allocator_type())
    { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }

This should create a default-initialized Int, then copy it into each
element of the vector.

--
Regards,
Ivan J. Johnson     C++ consulting and object-oriented
ijohnson (at)           design in Sacramento, CA
alum (dot) mit (dot) edu


Sent via Deja.com http://www.deja.com/
Before you buy.

      [ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]