|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-06 22:44:50
----- Original Message -----
From: "rwgk" <rwgk_at_[hidden]>
> --- In boost_at_y..., "David Abrahams" <david.abrahams_at_r...> wrote:
> > Checking whether the destructor is trivial is the wrong check:
> >
> > int destroyed;
> > struct X
> > {
> > X::~X() { ++destroyed; }
> > };
>
> ??? Would this ~X qualify as a trivial destructor?
No, and that's my point. There's no reason you couldn't skip
initializing members for a type with this destructor, if appropriate.
But only the author of X will know whether it's appropriate.
> What I had in mind is:
>
> X::~X() {}
>
> Either user defined or supplied by the compiler (and of course, all
> types that X inherits from directly or indirectly also have to have a
> constructor that "does nothing.")
Yes, that's the definition of trivial destructor, but it's just not the
right criterion for deciding whether members must be initialized in the
constructor. For example, one member might be a type with a trivial
destructor but whose constructor does something important that can't be
skipped.
> It seems to me that our "Enhanced POD" idea is very similar, just
> seen from a different angle.
Yes, but nobody is proposing (I don't think) that someone other than the
author of an "enhanced POD" type gets to decide that it acts like an
enhanced POD.
> > Well, that's what I was referring to in my previous message (and the
> > sanity of the implementor has never been a consideration ;-P),
>
> This makes (keeps!) the language very unwieldy for people that find it
> necessary to implement their own containers (like myself). You cannot
> assume that the standard provides everything anybody could ever need.
Note the smiley. But seriously,
1. When we say "implementor" in a standards context we're talking about
authors of C++ (compiler/standard lib) implementations
2. I don't think my proposal creates any new problems for those people.
> > > Eventually type traits are required anyway, so why not make the
> > > interface explicit?
>
> > I don't see what type traits have to do with it.
>
> Same argument: IMO the language should provide /portable/ means
> for implementing efficient containers.
> At the moment it looks to me that type traits are involved one
> way or another
Sure, but I mean that I don't understand how the involvement of type
traits impacts the decision we're trying to make about the interface for
avoiding initialization.
> : in my proposal they are used for safety checks,
> in your proposal you also seem to rely on the availability of
> type traits:
>
> You wrote:
> > > It could, but it would require that the container
> > > implementor specialize the constructors for the case where
> > > the container's value_type is POD and the Iterator's
> > > value_type is uninitialized.
>
> > > vector(size_t n, uninitialized);
> > >
> > > (where uninitialized is a typename) is much more intuitive.
> >
> > That's not legal syntax. You can't pass a typename as a function
> > argument.
>
> This is the declaration of the constructor and it definitely works
> for my array family.
Oops, sorry.
> > I think you're viewing it from the wrong angle. The way I see it,
> it's
> > using a a conversion from uninitialized to complex<> when U ==
> > uninitialized. That just happens not to initialize the members.
>
> Your view has some elegance, but then each type needs to
> know how it is constructed from the type uninitialized.
Only those types for which such a construction is appropriate. I claim
that nobody other than the type's author can determine whether that's
the case for a type with a non-trivial constructor.
> How
> could that work for types in, e.g. proprietary libraries
> that I cannot change? You "delocalize" the problem of
> "initializing a container" in the sense that the designer
> of a user-defined type has to consider what happens when
> his type is used as the value type of a container. To me it
> seems much more desirable that the container adjusts to the
> value-type rather than vice versa.
Somehow I don't think the issue of whether a type must be initialized is
a container-specific issue:
template <class T>
void f(T x)
{
T temporary(uninitialized);
...
temporary = x;
...
};
> > Ultimately, I don't think you can/should locate the smarts in the
> > vector.
>
> Our views seem to be orthogonal...
Apparently. However, you're the user with the real needs for avoiding
initialization; I am just a language-lawyer gadfly. I think you should
write something up which first explains the problem carefully and
follows with a proposed solution that fits /your/ view of the world. If
the rest of the committee agrees with your approach, I certainly won't
try to convince them to do otherwise.
> > The right place to locate information about whether X can be
> constructed
> > in a particular way is in X, preferably in a constructor.
>
> Again, this implies that any user-defined type has to be
> made "container compatible." This idea makes me shudder,
> especially since the alternative seems so obvious to me. My
> experience also shows that it works well in practice.
There's also no substitute for a theorem with implementation experience
behind it. It's very important to mention that in any proposal as it
carries lots of weight.
> P.S.:
>
> > > P.S.: In some sense this issue is more pressing than the
> > > complex<T> question: complex<T> mostly works OK, there is
> > > just no promise that it will work on new platforms.
> >
> > ??? of course there is - the standard makes all kinds of promises
> that
> > it will work
> >
> > But aren't you still dissatisfied with all of the issues of layout?
>
> That exactly is the point: all implementations known to me
> provide the desired layout (i.e. "work OK") even though the
> standard does not give a guarantee for this.
Ah, I understand. You're not talking about std::complex<> here, but
about the implementations of std::complex<> that you've used.
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk