Open ntrel opened 1 year ago
Yes, this is ... kind of hard to fix. The problem is that we'd need control flow analysis (or runtime errors) to catch cases where there exist flows through the constructor that don't set a field. At the limit, this is no-shit halting-problem tier undecidable.
I could hack something like "every field in the struct must have at least one assignment somewhere in the constructor", but I fear this would only give the false impression of safety.
Yes, some kind of basic flow analysis would be needed. If implemented like cppfront, the following code would error:
this(){
if (random!bool()) // line 12
c = new C;
}
objembed:12: Error: `if` statement initializes `c` in only one branch
Requiring if
to initialize a member in both branches if it is initialized in either seems a pragmatic way to solve the halting problem.
Okay, I'm gonna say that yes, I could do that, but I'm not gonna in the short and medium term. It seems a lot of effort for a mid improvement, and a lot of compiler machinery that wouldn't be used anywhere else. (Neat is relatively less reliant on compiler analysis than some other languages.)
Patches, as usual, welcome!
It seems a lot of effort for a mid improvement
For now perhaps an out contract for structs with non-nullable members could be added in constructors that asserts that those members are not null. Later the if
branch checking could be implemented and the out contracts removed (though the former can have false positives unlike the latter).
a lot of compiler machinery that wouldn't be used anywhere else
This would also be useful to ensure a struct with both a defined constructor and destructor is actually constructed and not left as T.init. This would guarantee that such structs do not have to handle T.init in their destructor (which has a runtime cost as well as a design cost to detect the init value). Then if there is no initialization of the struct, the compiler can avoid calling the destructor or allowing it to be copied. (I also raised this here).
Patches, as usual, welcome!
Thanks, I haven't looked at the source yet. (I'm a bit put off by the compile time as I'm spoilt by dmd ;-)).
Initial compile time is high, but follow-up should be fine as the cache is warm.
./build.sh
builds the compiler with optimization. This is usually the right move, but can be turned off with FAST= ./build.sh
.
That's a good idea with the out-condition assert! I'll put it on the TODO list.
Note that I'm distracted ATM making a toy cpu in VHDL.
Declaring
S s;
gives:But declaring
S.this
without initialization ofc
is not caught.s.c
is thennull
.