On 10/10/12 6:45 AM, Don Clugston wrote:
On 10/10/12 11:21, Jonathan M Davis wrote:
On Monday, October 08, 2012 18:47:43 Malte Skarupke wrote:
So I really can't think of a reason for why you wouldn't want
this. Yet this discussion has happened several times already.
There is clear demand for it and very good reasons, such as those
mentioned in all the linked discussions.

So why is this being rejected?

It buys you pretty much nothing. There are plenty of places in the
language
where init is required (e.g. member variables that can't be directly
initialized and the elements in an array). So, init _will_ be used              
                
regardless
of what you do with the default constructor. If you want to prevent
that, then
you need to disable init, which we can already do. But you're not
going to get
those things initialized with the default constructor, which kind of
defeats
the purpose of the default constructor. If you can't guarantee that every
instance which isn't explicitly constructed is default constructed, then
what's the point?

Of course there would be no point.
You have not answered the question. The issue is, WHY can we not
guarantee that that the struct default constructor is called?

We could (after all, C++ does it). There are a few disadvantages to doing so, however.

1. Defining static data is more difficult. Currently, all static data is statically-initialized. With default constructors, we'd need to define the pre-construction state of such objects anyway, and then change the compiler to call constructors prior to main(). I find the current design simpler and easier to use.

2. Creating a temporary object cannot be anymore assumed to be a O(1), no-resources-allocated deal. Instead, generic code must conservatively assume that objects are always arbitrarily expensive to create. That makes some generic functions more difficult to implement.

3. Two-phase object destruction (releasing state and then deallocating memory), which is useful, is made more difficult by default constructors. Essentially the .init "pre-default-constructor" state intervenes in all such cases and makes it more difficult for language users to define and understand object states.

4. Same as above applies to an object post a move operation. What state is the object left after move? C++'s approach to this, forced by the existence of default constructors and other historical artifacts, has a conservative approach that I consider inferior to D's: the state of moved-from object is decided by the library, there's often unnecessary copying, and is essentially unspecified except that "it's valid" so the moved-from object can continue to be used. This is in effect a back-door introduction of a "no-resources-allocated" state for objects, which is what default constructors so hard tried to avoid in the first place.

5. There are a few minor issues such as correct array creation etc. but I don't consider them decisive.

There are obvious disadvantages of the lack of a default constructor. I believe they are overcome by the advantages, although clearly reasonable people may disagree.

I have a vague memory that Walter mentioned a technical difficulty once
but I don't remember anything about what it was.

I can't imagine what it would be. Even in the worst case, it would be
possible to run CTFE on the default constructor in order to create
..init. This would limit the default constructor to things which are
CTFEable, but even that would still be useful for templated structs.

Allowing a default constructor that's computable during compilation would be a very interesting idea.

Really, there does not seem to me to be any point in having an invariant
for a struct, without a default constructor.

Could you please give a few examples? (Honest question.) Most structures I define have an obvious quiescent state that vacuously satisfies the invariant. Exceptions that come to mind are: (a) value types that must always allocate something on the heap, see e.g. the contortions in std.container; (b) values as permits (the existence of the value guarantees a resource has been secured, as in scoped locks on mutexes).


Andrei

Reply via email to