Suggestion: class object init value change & new compiler warning message
Kristian
kjkilpi at gmail.com
Wed Aug 23 08:09:36 PDT 2006
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