November 30, 2018
On Friday, 30 November 2018 at 06:15:29 UTC, O-N-S (ozan) wrote:
> On Monday, 19 November 2018 at 21:23:31
> On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote:
>>
>> I'm not the only one who has done this. I can't find it right now, but I've seen at least one person open a bug report because they misunderstood this as a bug in dmd.
>>
>> I have been told a couple of times that this isn't something that needs to be patched in the language, but I don't understand. It seems like a very easy way to generate a segfault (and not a NullPointerException or whatever).
>>
>
> I love Null in an empty class variable and I use it very often in my code. It simplifies a lot.
>
> What would be a better way? (practical not theoretical)
>
> Regards Ozan

A better way is to always initialise.

Invalid states should be unrepresentable.
November 30, 2018
On Friday, 30 November 2018 at 12:00:46 UTC, Atila Neves wrote:
> On Thursday, 29 November 2018 at 18:31:41 UTC, SimonN wrote:
>> On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote:
>>> When I was first playing with D, I managed to create a segfault
>>
>>> What's the reasoning for allowing this?
>>
>> 100 % agree that there should be non-nullable class references, they're my main missing feature in D. Likewise, I'm astonished that only few D users wish for them.
>
> https://github.com/aliak00/optional/blob/master/source/optional/notnull.d
>
> "But I don't like the verbosity!"
>
> alias MyClass = NotNullable!MyClassImpl;

Huh neat, though it would nice to allow conversion of Nullable to NotNullable via runtime conditional checking.

NotNullable!MyClassImpl = (MyClassImpvar != Null) ? MyClassImpvar : new MyClassImpvar();
November 30, 2018
On Friday, 30 November 2018 at 15:32:55 UTC, 12345swordy wrote:
> On Friday, 30 November 2018 at 12:00:46 UTC, Atila Neves wrote:
>> On Thursday, 29 November 2018 at 18:31:41 UTC, SimonN wrote:
>>> On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote:
>>>> [...]
>>>
>>>> [...]
>>>
>>> 100 % agree that there should be non-nullable class references, they're my main missing feature in D. Likewise, I'm astonished that only few D users wish for them.
>>
>> https://github.com/aliak00/optional/blob/master/source/optional/notnull.d
>>
>> "But I don't like the verbosity!"
>>
>> alias MyClass = NotNullable!MyClassImpl;
>
> Huh neat, though it would nice to allow conversion of Nullable to NotNullable via runtime conditional checking.
>
> NotNullable!MyClassImpl = (MyClassImpvar != Null) ? MyClassImpvar : new MyClassImpvar();
I meant new MyClassImp(), but you get the idea.
December 01, 2018
isocpp.org just had a link to a blog post where someone makes a case for uninitialized variables in C++ being an advantage in that you can potentially get a warning regarding use of an uninitialized variable that points out an error in your code.

https://akrzemi1.wordpress.com/2018/11/22/treating-symptoms-instead-of-the-cause/


December 01, 2018
On Saturday, 1 December 2018 at 00:32:35 UTC, Tony wrote:
> isocpp.org just had a link to a blog post where someone makes a case for uninitialized variables in C++ being an advantage in that you can potentially get a warning regarding use of an uninitialized variable that points out an error in your code.
>
> https://akrzemi1.wordpress.com/2018/11/22/treating-symptoms-instead-of-the-cause/

This is grat when it works, but the problem is that it would be gargantuan effort -and compile time sink- to make it work perfectly. When it's just about if-else if chains, switches or boolean logic as in the example, the analysis won't be too complicated. But swap those booleans out for a string, and make the conditions to test whether it's a phone number, and whether it satisfies some predicate implemented in a foreign langauge, and you'll see where the problem is.
December 01, 2018
On Friday, 30 November 2018 at 15:32:55 UTC, 12345swordy wrote:
> NotNullable!MyClassImpl = (MyClassImpvar != Null) ? MyClassImpvar : new MyClassImpvar();

AFAIK it's something like
NotNullable!MyClassImp m = MyClassImpvar.orElse(new MyClassImp());
December 01, 2018
On Saturday, 1 December 2018 at 11:16:49 UTC, Dukc wrote:
> This is great when it works, but the problem is that it would be gargantuan effort -and compile time sink- to make it work perfectly. When it's just about if-else if chains, switches or boolean logic as in the example, the analysis won't be too complicated. But swap those booleans out for a string, and make the conditions to test whether it's a phone number, and whether it satisfies some predicate implemented in a foreign language, and you'll see where the problem is.

I think he is just talking about the compiler or static analyzer seeing if a variable has been given a value before it is used, not if it was given a valid value.
December 01, 2018
On Sat, Dec 01, 2018 at 06:30:05PM +0000, Tony via Digitalmars-d-learn wrote:
> On Saturday, 1 December 2018 at 11:16:49 UTC, Dukc wrote:
> > This is great when it works, but the problem is that it would be gargantuan effort -and compile time sink- to make it work perfectly. When it's just about if-else if chains, switches or boolean logic as in the example, the analysis won't be too complicated. But swap those booleans out for a string, and make the conditions to test whether it's a phone number, and whether it satisfies some predicate implemented in a foreign language, and you'll see where the problem is.
> 
> I think he is just talking about the compiler or static analyzer seeing if a variable has been given a value before it is used, not if it was given a valid value.

But that's precisely the problem. It's not always possible to tell whether a variable has been initialized. E.g.:

	int func(int x) {
		int *p;

		if (solveRiemannHypothesis()) {
			p = &x;
		}

		...

		if (solveArtinsConjecture()) {
			*p++;
		}
		return x;
	}

For arbitrarily complex intervening code, determining whether or not a certain code path would take (that would initialize the variable) is equivalent to solving the halting problem, which is undecidable.

In the above contrived example, Artin's conjecture is implied by the Riemann hypothesis, so the second if statement would only run if p is initialized. But there is no way the compiler is going to be able to deduce this, especially not during compile time. So it is not possible to correctly flag p as being initialized or not when it is dereferenced.

Therefore, leaving it up to the compiler to detect uninitialized variables is unreliable, and therefore any code that depends on this cannot be trusted. Code like the above could be exploited by a sufficiently sophisticated hack to make the uninitialized value of p coincide with something that will open a security hole, and the compiler would not be able to reliably warn the programmer of this problem.

Uninitialized variables are *not* a good thing, contrary to what the author of the article might wish to believe.


T

-- 
The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5
December 01, 2018
On Saturday, 1 December 2018 at 19:02:54 UTC, H. S. Teoh wrote:
> But that's precisely the problem. It's not always possible to tell whether a variable has been initialized. E.g.:
>
> 	int func(int x) {
> 		int *p;
>
> 		if (solveRiemannHypothesis()) {
> 			p = &x;
> 		}
>
> 		...
>
> 		if (solveArtinsConjecture()) {
> 			*p++;
> 		}
> 		return x;
> 	}

If you are willing to loose some precision you can still analyse this. Google abstract interpretation.

For instance, after the first if the value of p is (&x || null). Since the compiler can prove which branch is taken, the analyse has to assume both are.

Inside the second if, p gets dereferenced, but since p is (&x || null) - that is, it might be null - that is a compile time error.

The take away is that you don't need to know what code path will be taken, you just combine both states.
December 01, 2018
On Saturday, 1 December 2018 at 20:41:53 UTC, Sebastiaan Koppe wrote:
> Since the compiler can prove which branch is taken, the analyse has to assume both are.

*can't*