November 28, 2018
On Tuesday, 27 November 2018 at 12:03:20 UTC, Sebastiaan Koppe wrote:
> On Tuesday, 27 November 2018 at 10:59:03 UTC, Alex wrote:
>> There exist
>>
>> auto val = Handle.init;
>>
>> 1. How do you treat this?
> I have no idea. Logically I would say that - in my case - the val is invalid.
>
>> 2. Why do you don't want to treat the handle after movement the same way?
> Because the handle refers to an underlying resource, and any access to that resource through that handle is invalid after a move. Much like one doesn't want to call .release() twice on an unique(T) wrapper type.
>
> Sure, I could put in a runtime check, but then I get runtime errors and I rather have compile time errors.

So ... what you want is this:

"Compiler, ensure that there is no possible execution-flow path in which this variable is ever set to 0."

We can actually attempt to prove that, using SMT or other logic solvers, though it will most likely say that there is set up inputs and flow-decisions which will result in the variable set to 0, and it can even give you an example.

You can then take that example and remove the invalid case, for the input provided.

This is a massive amount of work to get right.
November 28, 2018
On Tuesday, 27 November 2018 at 08:00:22 UTC, Sebastiaan Koppe wrote:
> I have a non-copyable struct and I really want a compiler error whenever I access it after it has been moved.
>
> ---
> struct Handle {
>     ...
>     @disable this(this);
>     ...
> }
>
> void main() {
>     import std.algorithm : move;
>     auto handle = getOne();
>     auto second = handle.move;  /// line 14
>     auto third = handle.move;    ///  <- compiler error, variable handle is invalid after line 14
> }
> ---
>
> I believe this would prevent some nasty bugs when dealing with these structs.
>
> What do you think?

I have always wanted a feature in C that would let me explicitly tell the compiler that a variable is no longer in scope (some sort of unset of a variable). This would be useful to do defensive programming against use-after-free of pointers to allocated memory and such.

Though it would be nice to have the compiler auto-detect these kinds of things, maybe having the programmer explicitly request this might be way easier to implement.

November 28, 2018
On Wednesday, 28 November 2018 at 09:17:39 UTC, sanjayss wrote:
> I have always wanted a feature in C that would let me explicitly tell the compiler that a variable is no longer in scope (some sort of unset of a variable). This would be useful to do defensive programming against use-after-free of pointers to allocated memory and such.
>
> Though it would be nice to have the compiler auto-detect these kinds of things, maybe having the programmer explicitly request this might be way easier to implement.

Yeah. It would be awesome if the programmer could 'taint' a variable as invalid. Even if that doesn't propagate in all cases.
November 28, 2018
On Wednesday, 28 November 2018 at 09:11:48 UTC, Stefan Koch wrote:
> So ... what you want is this:
>
> "Compiler, ensure that there is no possible execution-flow path in which this variable is ever set to 0."

Almost. I want to prevent usage *after* it is set to 0. Similar to how the compiler already recognises this error:

---
void main() {
  int* p = null;
  (*p) = 5;  // <- Error: null dereference in function _Dmain
}
---

Which more and more languages already provide. Swift, Kotlin etc.
November 28, 2018
On Wednesday, 28 November 2018 at 09:30:21 UTC, Sebastiaan Koppe wrote:
> On Wednesday, 28 November 2018 at 09:11:48 UTC, Stefan Koch wrote:
>> So ... what you want is this:
>>
>> "Compiler, ensure that there is no possible execution-flow path in which this variable is ever set to 0."
>
> Almost. I want to prevent usage *after* it is set to 0. Similar to how the compiler already recognises this error:
>
> ---
> void main() {
>   int* p = null;
>   (*p) = 5;  // <- Error: null dereference in function _Dmain
> }
> ---
>
> Which more and more languages already provide. Swift, Kotlin etc.

Sure, catching some simple cases is definitely doable, if someone has the compiler chops (or is prepared to learn) and some time to dedicate to it.

I suspect if it was a small code change and had a zero false-positive rate (I.e. only caught things that *definitely* were wrong) then it would be accepted. Large code change -> uncertain. Any false positives that forbid valid programs -> unlikely to be accepted.

That's just my feeling though, who knows....
November 28, 2018
On Wednesday, 28 November 2018 at 09:17:39 UTC, sanjayss wrote:
> On Tuesday, 27 November 2018 at 08:00:22 UTC, Sebastiaan Koppe wrote:
>> [...]
>
> I have always wanted a feature in C that would let me explicitly tell the compiler that a variable is no longer in scope (some sort of unset of a variable). This would be useful to do defensive programming against use-after-free of pointers to allocated memory and such.


{
    void* ptr = malloc(5);
}

// ptr no longer in scope

November 28, 2018
On Wed, Nov 28, 2018 at 04:49:02PM +0000, Atila Neves via Digitalmars-d wrote:
> On Wednesday, 28 November 2018 at 09:17:39 UTC, sanjayss wrote:
> > On Tuesday, 27 November 2018 at 08:00:22 UTC, Sebastiaan Koppe wrote:
> > > [...]
> > 
> > I have always wanted a feature in C that would let me explicitly tell the compiler that a variable is no longer in scope (some sort of unset of a variable). This would be useful to do defensive programming against use-after-free of pointers to allocated memory and such.
> 
> 
> {
>     void* ptr = malloc(5);
> }
> 
> // ptr no longer in scope

Yeah, this seems to be a not-very-well-known aspect of syntax common across C, C++, Java, and D:

	ReturnType myFunc(Args args) {
		int var1;
		someCode();
		{
			int var2;
			someOtherCode();
		}
		// var2 no longer in scope, but var1 still is.
		{
			// Can reuse identifier 'var2' without conflict
			float var2;
			yetMoreCode();
		}
		etcetera();
	}

It's a very useful construct in ensuring that temporaries don't last longer than they ought to. (Syntactically anyway... the compiler may or may not actually translate that directly in the executable. But the point is to avoid programmer slip-ups.)


T

-- 
In theory, there is no difference between theory and practice.
November 28, 2018
On 11/28/18 11:49 AM, Atila Neves wrote:
> On Wednesday, 28 November 2018 at 09:17:39 UTC, sanjayss wrote:
>> On Tuesday, 27 November 2018 at 08:00:22 UTC, Sebastiaan Koppe wrote:
>>> [...]
>>
>> I have always wanted a feature in C that would let me explicitly tell the compiler that a variable is no longer in scope (some sort of unset of a variable). This would be useful to do defensive programming against use-after-free of pointers to allocated memory and such.
> 
> 
> {
>      void* ptr = malloc(5);
> }
> 
> // ptr no longer in scope
> 

I think what the request is that you have variables with overlapping scope.

For example:

void *ptr1 = malloc(5);
void *ptr2 = malloc(5);
...
free(ptr1); // end ptr1 scope
...
free(ptr2); // end ptr2 scope

Which isn't possible by adding a nested scope.

But in any case, this doesn't fix all the problems anyway, you could have another alias to the same data, free that alias, and then ptr1 is still "valid".

-Steve
November 28, 2018
On Wed, 28 Nov 2018 12:47:07 -0500, Steven Schveighoffer wrote:
> But in any case, this doesn't fix all the problems anyway, you could have another alias to the same data, free that alias, and then ptr1 is still "valid".

Move constructors and init'ing out the moved variable address that, no?
November 28, 2018
On 11/28/18 1:59 PM, Neia Neutuladh wrote:
> On Wed, 28 Nov 2018 12:47:07 -0500, Steven Schveighoffer wrote:
>> But in any case, this doesn't fix all the problems anyway, you could
>> have another alias to the same data, free that alias, and then ptr1 is
>> still "valid".
> 
> Move constructors and init'ing out the moved variable address that, no?
> 

Not sure what you mean. What I'm talking about is this:

int *ptr1 = (int *)malloc(sizeof(int));
int *ptr2 = ptr1;

free(ptr2);

*ptr1 = 5;

If we have a hypothetical C compiler that prevents use of ptr2 after free, it probably doesn't know about the link to ptr1, to make that also unusable.

Indeed the runtime solution is much more possible.

-Steve