December 08, 2022
On 12/6/2022 10:24 AM, Iain Buclaw wrote:
> I wouldn't see lack of default initialization as a source of bugs, rather an attack vector.  It isn't a concern that there are uninitialized data pointing to garbage causing your program to do something wild/unexpected.  The concern is when it might point to useful information.

Default initializing it to null doesn't present an attack vector.
December 08, 2022
On 12/6/2022 5:33 AM, deadalnix wrote:
> Compiler can do control flow analysis, so they can force you to initialize things before you use them. This is the right solution to that problem.

Your are correct, but this isn't done because it makes compiles 10x or more slower.
December 08, 2022
On 12/6/2022 3:58 PM, Timon Gehr wrote:
> Variables are scoped within the innermost block that they are declared in. Languages like Python that don't have block-local scoping just don't have this particular problem (there's plenty of things to dislike about Python, but this is something it got right I think):
> 
> ```python
> # note there is no x declared here
> if cond:
>      x = f()
> else:
>      x = g()
> print(x)
> ```

That looks like a matter of taste rather than righteousness.


> A particularly egregious case is the do-while loop:
> 
> ```d
> do{
>      int x=4;
>      if(condition){
>          ...
>          x++;
>      }
>      ...
> }while(x<10); // error
> ```
> 
> Just... why? x)

Because we love to annoy people.

December 08, 2022
On Thursday, 8 December 2022 at 20:52:26 UTC, Walter Bright wrote:
> On 12/6/2022 5:33 AM, deadalnix wrote:
>> Compiler can do control flow analysis, so they can force you to initialize things before you use them. This is the right solution to that problem.
>
> Your are correct, but this isn't done because it makes compiles 10x or more slower.

would it be possible to have it behind a compiler switch if it's a useful tool to catch bugs. it's enough to run extra checks one before release.
December 09, 2022
On 12/8/22 21:57, Walter Bright wrote:
> On 12/6/2022 3:58 PM, Timon Gehr wrote:
>> Variables are scoped within the innermost block that they are declared in. Languages like Python that don't have block-local scoping just don't have this particular problem (there's plenty of things to dislike about Python, but this is something it got right I think):
>>
>> ```python
>> # note there is no x declared here
>> if cond:
>>      x = f()
>> else:
>>      x = g()
>> print(x)
>> ```
> 
> That looks like a matter of taste rather than righteousness.
> ...

I am quite confident that C scoping is not how it should be done, then people asked what I think is the right solution, so I provided that.

Almost everything is a trade-off, but this fixes the issue without introducing spurious behavior, limitations or syntactic incantations.

D's solution of "just put a null state into every type" is probably close to my least favorite part of the language. Yes, that's a preference, but it's backed up by more reasoning than "YMMV".

> 
>> A particularly egregious case is the do-while loop:
>>
>> do{
>>      int x=4;
>>      if(condition){
>>          ...
>>          x++;
>>      }
>>      ...
>> }while(x<10); // error
>> ```
>>
>> Just... why? x)
> 
> Because we love to annoy people.
> 

Well, for D specifically, I hope the answer is just that the reason is that C does it this way.
December 09, 2022
On Thursday, 8 December 2022 at 20:52:26 UTC, Walter Bright wrote:
> On 12/6/2022 5:33 AM, deadalnix wrote:
>> Compiler can do control flow analysis, so they can force you to initialize things before you use them. This is the right solution to that problem.
>
> Your are correct, but this isn't done because it makes compiles 10x or more slower.

I do not expect this to be that expensive. It is simpler than the escape analysis that is being baked in the language right now, and roughly on par with keeping track of constructors/destructors.
December 09, 2022
On 12/8/22 21:47, Walter Bright wrote:
> On 12/5/2022 3:58 PM, Timon Gehr wrote:
>> Default initialization does not even fix all initialization issues, it just makes them reproducible.
> 
> As I mentioned in another post, making them reproducible is a huge deal.

Absolutely, I agree with that. It's just that I think eliminating them statically makes even more sense.

> Leaving variables uninitialized is Heisenbug City. Testing finds the reproducible ones, not the Heisenbugs.
> 

Yes. (This is why I don't want UB in general.)
December 08, 2022
On 12/8/2022 1:02 PM, Zealot wrote:
> would it be possible to have it behind a compiler switch if it's a useful tool to catch bugs. it's enough to run extra checks one before release.

I used to have it when the optimizer was run, but people just didn't like sometimes seeing the error and sometimes not.
December 08, 2022
On 12/8/2022 4:24 PM, deadalnix wrote:
> I do not expect this to be that expensive. It is simpler than the escape analysis that is being baked in the language right now, and roughly on par with keeping track of constructors/destructors.

I've done it. It's expensive. It is not on par with ctors/dtors which rely on FILO scope analysis, not data flow.

D's borrow checker does do DFA, and it's slow, and one of the reasons why it's active only with @live annotations. Rust uses DFA, and is notoriously slow.

D always initializes variables, and then the (optional) optimization pass removes the unneeded ones. This is a reasonable approach.

December 08, 2022
On 12/5/2022 8:35 PM, Siarhei Siamashka wrote:
> Many of the integer overflow bugs are caught by the C++ compiler via UBSAN during the development and never reach the end users.

While that is a good option to have on the compiler, it will only never reach the end users if there is a test case that would trigger an overflow.