Suggestion: class object init value change & new compiler warning message

Chad J gamerChad at _spamIsBad_gmail.com
Wed Aug 23 10:10:44 PDT 2006


I disagree with this.

It allows an object with an invalid value to pass of as valid while your 
program continues executing.  This makes it difficult to check for 
uninitialized values at runtime.  Checking for uninitialized values at 
compile time is quite difficult because people can write arbitrarily 
complex code, as xs0 pointed out.

Also, I usually want my references to start off knownly invalid and not 
allocate unnecessary objects.  If this were used, I would have to write 
'= null;' very, very, frequently.  I suppose it's arguable that 
explicitly initializing things to null is a better practice.  I wonder 
how much current D code is actually written with explicit null 
initializiation though.

In a way I wish structs were initialized to null, though I wonder how 
that would work with the whole value type idea.  Currently I feel that 
the wisest thing to do is exactly what D does now - distinguish between 
value and reference types, and give each their unique properties.

Kristian wrote:
> Let we have:
> 
> struct Stru {...}
> 
> class Obj {
>     this() {...}
>     this(int val) {...}
> 
>     bool f() {...}
> }
> 
> void func() {
>     Stru stru;  //valid structure, not NULL as 'obj3'
>     Obj obj1 = new Obj;
>     Obj obj2 = new Obj(10);
>     Obj obj3;  //"obj3 = NULL;"
> }
> 
> There will be lot of "object = new SomeClass" in code around the globe, 
> as  in the example. I think it's a much more common situation than  
> initializing an object with NULL. Hence objects should be initialized 
> with  new objects by default. That is, 'func()' would become:
> 
> void func() {
>     Stru stru;
>     Obj obj1;      //"obj1 = new Obj;"
>     Obj obj2(10);  //"obj2 = new Obj(10);"
>     Obj obj3 = NULL;
> }
> 
> This reduces redundant code: a class name is not anymore used twice per  
> object.
> 
> The amount of typing required is also smaller; fewer possible typos. 
> (It's  pain in the #!%%# to write looogn class names over and over again.)
> 
> (This suggestion won't break old code.)
> 
> 
> Compiler could also optimize the initialization values: if a value is  
> assigned to an object before it's used, then it's initialized with NULL  
> instead of a new object.
> 
> void func() {
>     Stru stru;
>     Obj obj1;      //"obj1 = new Obj;"
>     Obj obj2(10);  //"obj2 = new Obj(10);"
>     Obj obj3;      //"obj3 = NULL;"
> 
>     if(obj1.f()) {...}  //used without initialization
> 
>     obj3 = new Obj;  //assigned before used
> }
> 
> That would be optimal situation of course. Clean and short syntax.
> 
> 
> But can the compiler know which init value to use?
> The very basic checking is done, of course, as follows:
> 
> 1) Get the first occurance of an object.
> 2) If it's on the left side of an assignment statement, it's inited 
> with  NULL.
> 3) Otherwise it's inited with a new object.
> 
> Even this simple solution gets very large proportion of the cases right  
> (IMHO). (If not, your coding style is weird. ;) )
> 
> You can make the checking smarter by taking pointers/references into  
> account.
> 
> For example, MS Visual Studio works as follows:
> 
> void func() {
>     int a;
>     int *ptr;
> 
>     ptr = &a;   //'ptr' is the same thing as 'a' now
>     *ptr = 1;   //this equals to "a = 1;"
>     a++;        //so, 'a' is not used here without initialization; no  
> warning message
> }
> 
> I think this kind of checking will get all the cases right (see below  
> though).
> 
> If I am wrong here, it should not be a problem. If the compiler  
> initializes a variable with a new object instead of NULL (which the  
> compiler must do if it's not sure), normally it's a very minor  
> inefficiency (because it happens very seldom). If necessary (writing 
> some  complex code, eh?), you could force the right init value to be used:
> 
>     Obj obj = NULL;
> 
> 
> 
> And here comes the suggestion #2:
> 
> If a variable is used without initialization, the compiler should warn  
> about it.
> 
> 
> 
> Of course, a variable can be set inside another function. For axample:
> 
> class Obj {...}
> 
> void setObj(out Obj o) {
>     o = new Obj;
> }
> 
> void func() {
>     Obj obj;  //"obj = new Obj;"
> 
>     setObj(obj);
> }
> 
> Note that compiler should not initialize 'obj' with NULL here, even if 
> it  would be possible in this very situation. If an init value would 
> depend on  how functions will handle their parameters, it would be a mess.
> 
> 
> It's 'interesting' to notice that Visual Studio does not warn in the  
> following cases:
> 
> void func2(int val) {
>     ...
> }
> void func3(int &val) {  //in D: "void func3(inout int val)"
>     ...
> }
> void func() {
>     int a;
> 
>     func2(a);  //no warning even if 'a' is used wihout initialization!
>     func3(a);  //no warning!
> }
> 
> In addition VS assumes that 'a' is set in 'func3()' because it _could_  
> modify it. For example:
> 
> void func() {
>     int a;
> 
>     func3(a);
> 
>     a++;  //no warning!
> }
> 
> All of these cases should cause a warning message.
> That is:
> 
> void func() {
>     int a;
> 
>     func2(a);  //warning
>     func3(a);  //warning
>     a++;       //warning
> }
> 
> Of course, only one warning message per variable is enough.



More information about the Digitalmars-d mailing list