February 02, 2014
On Sunday, 2 February 2014 at 12:42:47 UTC, Jonathan M Davis wrote:
> On Sunday, February 02, 2014 12:52:44 Timon Gehr wrote:
>> On 02/02/2014 04:39 AM, Jonathan M Davis wrote:
>> > I'm not sure how I feel about that, particularly since I haven't seen such
>> > data myself. My natural reaction when people complain about null pointer
>> > problems is that they're sloppy programmers (which isn't necessarily fair,
>> > but that's my natural reaction).
>> 
>> There is no such thing as 'naturality' that is magically able to justify
>> personal attacks in a technical discussion, even if qualified.
>
> Would you prefer that I had said "initial reaction" or "gut reaction?" I'm
> just saying that that's how I tend to feel when I see complaints about null
> pointers. I have never accused anyone of anything or otherwise attacked them
> because they complained about null pointers. That _would_ be rude.
>
>> The situation does not have to be unbearable in order to
>> improve it!
>
> True, but I don't even agree that null pointers are that big a deal in the
> first place. If we really want to add non-nullable pointers or references to
> the language, then we can. I don't think that that's necessarily a bad idea.
> But I doubt that I'll use them often, and I do think that the whole issue is
> frequently blown out of proportion.
>
> - Jonathan M Davis

Ideally you'd be using them wherever you use objects and pointers, as they'd be the default.
February 02, 2014
On Sunday, 2 February 2014 at 15:06:34 UTC, Idan Arye wrote:
> I think it's safe to assume that you - being a supporter of the non-null movement - write your own code in a way that tries to avoid the usage of null as much as possible.

You'd be wrong - I was against the not null thing for a long time, including while writing dom.d.

> If I have a class\struct `Foo` with a member field `bar` of type `Bar`, and an instance of `Foo` named `foo` that happens to have no `Bar`, I'll not add an extra boolean field just to indicate that `foo` has no `Bar` - I'll simply set `foo.bar` to null!

Me too, that's exactly what I did with Element parentNode for instance.

> And I'll use the fact that UFCS works perfectly fine when the first argument is null to build functions that accept `Bar` as first argument and do the null checking internally(if it's needed!) and safely call them on `foo.bar`.

Again. me too.


Some of my code would break with not null by default, but the amazing thing is it really isn't the majority of it, and since the compiler error would point just where it is, adding the Nullable! to the type is fairly easy.
February 02, 2014
On Sunday, 2 February 2014 at 18:33:05 UTC, Adam D. Ruppe wrote:
> On Sunday, 2 February 2014 at 15:06:34 UTC, Idan Arye wrote:
>> I think it's safe to assume that you - being a supporter of the non-null movement - write your own code in a way that tries to avoid the usage of null as much as possible.
>
> You'd be wrong - I was against the not null thing for a long time, including while writing dom.d.
>
>> If I have a class\struct `Foo` with a member field `bar` of type `Bar`, and an instance of `Foo` named `foo` that happens to have no `Bar`, I'll not add an extra boolean field just to indicate that `foo` has no `Bar` - I'll simply set `foo.bar` to null!
>
> Me too, that's exactly what I did with Element parentNode for instance.
>
>> And I'll use the fact that UFCS works perfectly fine when the first argument is null to build functions that accept `Bar` as first argument and do the null checking internally(if it's needed!) and safely call them on `foo.bar`.
>
> Again. me too.
>
>
> Some of my code would break with not null by default, but the amazing thing is it really isn't the majority of it, and since the compiler error would point just where it is, adding the Nullable! to the type is fairly easy.

OK, I see now. What you say is that even if some code will break, it'll be easy to refactor because the compiler will easily pinpoint the locations where `Nullable1!` should be added.

Well, I don't think it'll be that straightforward. In order for non-nullable-by-default to mean something, most APIs will need to use it and not automatically use `Nullable!`. While non-nullabe can be implicitly cast to nullable, the reverse is not true, and whenever a code fails to compile because it sends nullable-typed value to as a non-nullable argument it can't be fixed automatically - you'll need to check for nulls, and to actually decide what to do when the value is null.

Now, this is doable in your own code, but what if you use a third party library? That you are not familiar with it's source? Automatically downloaded from a repository that you have commit-rights to?
February 02, 2014
On Sunday, 2 February 2014 at 07:54:26 UTC, Jonathan M Davis wrote:
> On Saturday, February 01, 2014 19:44:44 Andrei Alexandrescu wrote:
>> On 2/1/14, 7:35 PM, deadalnix wrote:
>> > http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
>> 
>> Whoa, thanks. So the compiler figures null pointer dereference in C is
>> undefined behavior, which means the entire program could do whatever if
>> that does happen.
>
> I think that article clearly illustrates that some of Walter's decisions in D
> with regards to fully defining some stuff that C didn't define were indeed
> correct. Undefined behavior is your enemy, and clearly, it gets even worse
> when the optimizer gets involved. *shudder*
>
> - Jonathan M Davis

What you don't seem to understand is the associated cost.

Defining integer overflow to wrap around is easy and do not cost much. But in our case, it imply that the optimizer won't be able to optimize away load that it can't prove won't trap. That mean the compiler won"t be able to optimize most load.
February 02, 2014
On Sunday, 2 February 2014 at 10:58:51 UTC, Dicebot wrote:
> On Sunday, 2 February 2014 at 03:45:06 UTC, Andrei Alexandrescu wrote:
>> On 2/1/14, 7:35 PM, deadalnix wrote:
>>> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
>>
>> Whoa, thanks. So the compiler figures null pointer dereference in C is undefined behavior, which means the entire program could do whatever if that does happen.
>>
>> Andrei
>
> As far as I have understood previous posts, it is even worse than that - LLVM optimiser assumes that C semantics whatever high-level language is.
>
> deadalnix is that true?

It depends. For instance you can specify semantic of wrap around, so both undefined and defined overflow exists.

In the precise case we are talking about about, that really do not make any sense to propose any other semantic as it would prevent the optimizer to optimize away most load.
February 02, 2014
On 2/2/2014 1:19 PM, deadalnix wrote:
> But in
> our case, it imply that the optimizer won't be able to optimize away load that
> it can't prove won't trap. That mean the compiler won"t be able to optimize most
> load.

I do understand that issue, but I'm not sure what the solution is.
February 02, 2014
On Sunday, 2 February 2014 at 09:56:06 UTC, Marc Schütz wrote:
>
> auto x = *p;
> if(!p) {
>     do_something(x);
> }
>
> In the first step, the if-block will be removed, because its condition is "known" to be false. After that, the value stored into x is unused, and the dereference can get removed too.

With a good static analyzer, such as coverity, this program would be rejected anyway with "check_after_deref", if the compiler is smart enough to do the optimization, it could be smart enough to issue a warning as well!

February 02, 2014
On 2/2/14, 1:23 PM, deadalnix wrote:
> On Sunday, 2 February 2014 at 10:58:51 UTC, Dicebot wrote:
>> On Sunday, 2 February 2014 at 03:45:06 UTC, Andrei Alexandrescu wrote:
>>> On 2/1/14, 7:35 PM, deadalnix wrote:
>>>> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
>>>>
>>>
>>> Whoa, thanks. So the compiler figures null pointer dereference in C
>>> is undefined behavior, which means the entire program could do
>>> whatever if that does happen.
>>>
>>> Andrei
>>
>> As far as I have understood previous posts, it is even worse than that
>> - LLVM optimiser assumes that C semantics whatever high-level language
>> is.
>>
>> deadalnix is that true?
>
> It depends. For instance you can specify semantic of wrap around, so
> both undefined and defined overflow exists.
>
> In the precise case we are talking about about, that really do not make
> any sense to propose any other semantic as it would prevent the
> optimizer to optimize away most load.

A front-end pass could replace the dead dereference with a guard that asserts the reference is not null. More generally this is a matter that can be fixed but currently is not receiving attention by backend writers.

Andrei

February 02, 2014
On 02/03/2014 12:09 AM, Andrei Alexandrescu wrote:
>
> A front-end pass could replace the dead dereference with a guard that
> asserts the reference is not null.

I don't think this would be feasible. (The front-end pass would need to simulate all back-end passes in order to find all the references that might be proven dead.)

> More generally this is a matter that
> can be fixed but currently is not receiving attention by backend writers.
>
> Andrei

Yup.
February 02, 2014
On 2/2/14, 3:44 PM, Timon Gehr wrote:
> On 02/03/2014 12:09 AM, Andrei Alexandrescu wrote:
>>
>> A front-end pass could replace the dead dereference with a guard that
>> asserts the reference is not null.
>
> I don't think this would be feasible. (The front-end pass would need to
> simulate all back-end passes in order to find all the references that
> might be proven dead.)

Well I was thinking of a backend-specific assertion directive. Worst case, the front end could assign to a volatile global:

__vglobal = *p;


Andrei