Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-07 17:43:24


----- Original Message -----
From: "rwgk" <rwgk_at_[hidden]>

> From the paper:
> > This definition is appropriate for local variables, but not
> > for objects that are initialized as a result of executing
> > expressions of the form T(), because the objects yielded by
> > such expressions will be copied immediately, and should
> > therefore have values that are assured of being copyable.
>
> Why is this a problem for built-in types. Isn't it that we
> are just copying bytes? I am thinking "no constructor, no
> copy constructor, no destructor, no problem." What am I
> missing?

Technically, there are all kinds of restrictions on what you can do with
uninitialized memory when it's not being treated explicitly as an array
of chars. For example:

    int* x;
    int* y = x; // undefined behavior

It doesn't matter that int* is a POD in this case, because some obscure
machine has address registers which trap when you load them with invalid
pointers. The argument is similar for double.

> Interesting to see how much back-and-forth there was.
> However, the paper does not convince me that the global
> optimum was found, only a domain-specific optimum: much of
> the argumentation is based on addressing the particular
> needs of certain applications. I view the examples
> (map<int, int>, struct Customer) as evidence of a strong
> bias towards a certain domain. Not much attention is payed
> to huge arrays of built-in types. Only here (where I think
> the standard got it right):
>
> > struct T {
> > int x[100000];
> > };
> > Everyone agreed that
> > T t;
> > should not cause any initialization,
>
> But vector<int>(100000), which is generally much more
> useful, provides no facility to avoid the initialization?
> This makes no sense at all. In my universe this "is too
> much of a violation of the principle of least surprise."

Would this be more surprising? It appears to be what you are proposing:

    vector<int> x(100000);
    int y = x[0]; // undefined behavior

> Also, I cannot believe that an array package must be 120000
> lines long (Blitz++), in part to make the implementation of
> map<int, int> simpler.

I can't believe that Blitz++ spends any significant fraction of those
lines avoiding initialization.

> However, it is clear that the rules are essentially carved
> in stone and that any more criticism of the basic concepts
> is futile.

I'm not sure that's true, but I can understand wanting to pick your
battles.

> So what could be done to make C++ more suitable
> for numeric applications? I see two areas that should be
> addressed:
>
> 1. The standard containers should provide a facility to
> avoid the initialization of the data if they meet
> certain conditions (such as is-a-POD or, more generally,
> has-a-destructor-that-does-nothing).

I agree. I think we can look for more elegant ways to provide that
facility, but I don't think anyone will argue with the premise.

> 2. We need a predictable layout for certain non-POD types,
> foremost the topic of this thread (std::complex), but
> this would also be generally useful for applications
> that integrate C++ with e.g. C or Fortran, or, oops(!),
> assembler (as recommended by B. Stroustrup (see the the
> ublas front-page)).

Absolutely.

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk