Last update July 3, 2006

Feature Request List /
Auto Newing Of Classes

Auto New-ing of Classes at Declaration Time

All variables are pre-initialized in D to something useful. This is done to prevent the common bug of trying to use uninitialized variables. However, classes instances are initialized to null, which is mostly unhelpful.

Based on the premise that the most frequent coding practice when declaring new instances of a class is to code ...

 Foo AnInstance = new Foo;
I propose that the syntax ...
 Foo A; 
is a shorthand for ...
 Foo A = new Foo; 
And that when the coder explictly does not want the class instance to be constructed they would code ...
 Foo A = null; 

All current forms of constructor invocation syntax would remain untouched.


I disagree - it would change the behaviour of existing code. -- StewartGordon

  • (DerekParnell) Yes it would. But at what cost? We are not at v1.0 yet. Would be long term benefits out weigh that cost?
Moreover, what if the class doesn't have a parameterless constructor? Would you be forced to initialise it, or would it act just like an uninitialised local variable of primitive type (i.e. must be assigned before it can be accessed)? -- StewartGordon
  • (DerekParnell) Then there would be no change in behaviour. In other words, if the class did not have a parameterless constructor, then "Foo A;" would be exactly equivalent to "Foo A = null;"
    • Seems a confusing inconsistency to me. -- StewartGordon
      • I'm sorry. I'll use the term "default constructor" to mean "this(){ . . .}" for the purposes of this discussion. What I'm saying is that the rule would be - The idiom "[CLASSNAME] [ID];" would call the default constructor of class [CLASSNAME] if one has been defined otherwise it will invoke the default 'default constructor', which is to assign null to the [ID]. Seems so simple to me. I don't understand what it is that I'm missing. -- DerekParnell
        • Simply the strangeness that the presence or absence of a default constructor alters the meaning of a declaration, and that an apparently uninitialised declaration should have a side effect under certain conditions. -- StewartGordon
And what about contexts where the initialiser must be a compile-time constant? It would force you to initialise globals and struct/union/class members of class type to null, which would look a bit silly as it's the only allowable initialiser in the circumstances. -- StewartGordon
  • (DerekParnell) Then the coder would write "Foo A = new Foo(compile-time-constant);" just has they do now.
    • No they don't. A constructor call doesn't evaluate to a compile-time constant, regardless of its arguments. -- StewartGordon
      • I'm sorry, but I don't actually understand your point. Can you give an example of what you mean using current D syntax? -- DerekParnell
class Qwert {
    this(int yuiop) { ... }
    Qwert asdfg = new Qwert(42);
or more simply
class Hjkl {
    Hjkl zxcvb = new Hjkl;
        • Not valid code, as member initialisers have to be compile-time constants. -- StewartGordon
  • (DerekParnell) Or in the case where the construction parameters were not known until run time, currently we code ...
Foo A;
if (condition)
    A = new Foo(x);
    A = new Foo(y);
but with this proposal the method would be ...
Foo A = null;
if (condition)
    A = new Foo(x);
    A = new Foo(y);
    • In what context requiring initialisers to be compile-time constants is this valid code? -- StewartGordon
      • ?? It's not. I said "construction parameters were not known until run time" and thus they are not compile-time constants. Sorry I didn't make this clearer. -- DerekParnell
I suspect that this is a rarer occurance than the simple case of "Foo A;" to construct a default instance. Maybe its just an issue that I have. I'm frequently forgetting to code the " = new Foo" part whenever I declare a Foo instance and then having run time errors that are hard to track down. In this proposal, if a class doesn't have a default ctor, then there is no difference, otherwise one can design a light weight default ctor. -- DerekParnell

All variables are pre-initialized in D to something useful.

Not all variables are initialized to something useful, in fact, it's just the opposite (N|aN for floats, null for classes/arrays). The only exception are integral types, because they don't have a non-useful value in the same sense, so they're zeroed. The reason everything is initialized is not to provide a useful default value, but to prevent random behavior when using uninitialized variables. I think it would be best to leave things as-is, and perhaps introduce a shortcut like

new Foo a(x,y), b(z);

Reads better, if you ask me, and the construction is still explicit, like it should be. Or perhaps more simply, if the var name is followed by (params), it gets constructed; the problem there is that it looks exactly like a stack instance in C++, which may be problematic, because it isn't. -- XsZero?

Whatever! My whole point, and the one that people are not seeming to understand from my poor explanation, is that common idioms should be easy to write and read. That is the whole point of what I'm proposing. It has nothing to do with classes, initialization vs assignment, aggregates, C++, Java, etc, etc, etc,... Just that we should make reading and write code easier than it currently is. -- DerekParnell

IF D was to be consistent, we should be having to write

  int a = new int;
  int[] b = new int[];
  myStruct c = new myStruct;
  myClass d = new myClass;
From the coder's point of view, why do I have to use different syntax just because some datatypes are primitives, others are stack-based and others are heap-based? The compiler knows which is which, and it doesn't confuse them.

They all behave the same - "int a" allocates an integer on the stack and sets it to the default value, "int[] b" allocates a reference to an array on the stack and sets it to the default value (null), "myStruct c" allocates a struct on the stack and sets it to the default value, "myClass d" allocates a reference to an object on the stack and sets it to the default value (again null). What you want is actually different behavior for object references, not equal behavior. I don't have anything against a shorter syntax for "T t=new T", but it definitely should not be just "T t". -- XsZero?

    • However, the runtime behaviour of a null array and a null object is very different. The null array is actually (in effect) an "object" with .length 0 and .ptr null, but it does not segfault when you try to access it like that (even if set to null) A NullObject would be the equivalent of a null array, so they are very different... -- AndersFBjörklund
I think it's best as it is - it's very clear and obvious what's happening. It's not immediately obvious how to solve the issues of "what happens if there's no default constructor" and so on, and any solution would most likely be inelegant, confusing, and inconsistent. I think it would be better to err on the side of Java-like syntax (slightly wordy but logical and consistent) than C++-like syntax (total hodgepodge). -- JaredMoore?

FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: July 3, 2006 14:26 (diff))