Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-06 16:39:39


----- Original Message -----
From: "Ralf W. Grosse-Kunstleve" <rwgk_at_[hidden]>

>
> IMO complex<double>() should behave like double().

Agreed.

> OK, I happily go with your bet. Here is the new plan:
>
> 0. You do (have done already?) the Enhanced POD proposal (could I see
it?).

No, I don't.

Err, looking back at what I had, it appears I volunteered you for that
one (see below) ;^S.

I think mostly, the discussion below covers it, but let me know if you
think anything is missing.

> 1. complex<T> proposal:
> a. predictable layout to facilitate use of existing code
> b. members should be directly accessible (T& real() { return
re; })

Yes, though you only really need part a. to get part b.

> 2. propose additional constructors for containers (vector<T> and
valarray<T>):
> vector(size_t n, no_initialization_flag);
> valarray(size_t n, no_initialization_flag);
> - with compile time assertion that T has a trivial destructor.

I like this idea better:

First, we need a way to construct complex<> without initializing the
members, so we add a constructor

    complex(uninitialized);

Then we need a way to construct a vector of n uninitialized complexes:

    template <class U>
    vector(size_t n, U const& u)
    {
        // initializes each of n T objects with u.
    }

This is analogous to the existing constructor:

    template <class Iterator>
    vector(Iterator i1, Iterator i2) {}

In fact, there may be some problems with my suggestion; resolving all of
vector's constructor overloads is already tricky. If it's problematic we
can always fall back to using the above constructor with a special
iterator whose value type is "uninitialized". I like this in part
because it only requires changes to complex<> and not to the containers.

-------

Here is the transcript of my discussion with John Spicer of EDG about
the
restrictions on PODs, the rationale, and the reasons we need the
restrictions loosened.

-Dave

[Dave]
We have some bitter complaints about the liberal conditions which
cause a type to become non-POD, particularly the presence of any
constructor. We have some numerics experts preparing the specifics
(this came up because you can't convert a complex<double>* into a
double* portably), but I thought we should get your feedback about the
reasoning for the status quo...

[John]
PODs are supposed to be basically C structs, and can be manipulated
using mechanisms like memcpy. If a class has a constructor, the
thought is that you should be using constructors for things like
copying.

I think we need PODs, but it would be possible to add another kind of
object type that had known layout properties (e.g., no virtual
functions, no base classes).

[ed. note: by this I think John means that we ought to leave the
  concept "POD" alone, but a new concept which captures the
  restrictions we need is possible]

[Dave]
What's so bad about base classes?

They could be extremely useful in the context of PODs. Just look at
how often 'C' programmers simulate base classes by
embedding-and-casting, or other equally odious approaches (macros). If
we allowed base classes, at least implicit conversions (upcasts) would
work properly.

[John]
Don't the existing C++ language facilities handle those cases
sufficiently?

[Dave]
Not when you need to make a POD. For example, the Python API does
everything in terms of PyObject*. Every object has to start with a
PyObject at its head. Now suppose I want, essentially, this:

    class Foo : non_pod
    {
        ...
    };

    struct MyPyObject : PyObject
    {
        Foo* my_data;
    };

    Now it's no longer a POD, so instead I need to write:

    struct MyPyObject
    {
        PyObject head;
        Foo* my_data;
    };

Now I can't pass MyPyObject*s directly to the Python API anymore.

[ed. note: I see the ability to use inheritance with PODs (or
something with some of the same properties) as an important part of
making C++ "a better 'C'", which is one of its goals]

[John]
The low-level stuff you do, the more you limit implementation choices.
   ^--- [ed.: "more"? ]
For example, if you have an empty base, is it given storage at the
start of the derived class or not?

[Dave]
Implementors don't need that freedom as much as I need power and
predictability ;-)

[John]
Plus, of course, you'd have to limit it to single inheritence.

[Dave]
Not neccessarily, but if you insist I can live with it.

You could just say that struct mypod : podA, podB {};
has the same layout as struct mypod { podA a; podB b; };

[John]
Thanks for the explanation. Are you going to propose a change in this
area?

[Dave]
Yes, well, Ralf is going to write the proposal. He's an actual
numerics user with real concerns in this area. I think his
point-of-view will carry extra "street cred". I'm going to "sponsor"
his proposal as needed.


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