On 17/10/12 18:02, Timon Gehr wrote:
On 10/17/2012 01:49 PM, Don Clugston wrote:
On 01/01/12 13:50, Timon Gehr wrote:
On 01/01/2012 10:40 AM, Denis Shelomovskij wrote:
So, I'm a function `f`, I have an `immutable(type)[]` argument and I
want to store it for my friend `g` in an TLS variable `v`:
---
string v;
debug string sure;

void f(string s) { v = s; debug sure = s.idup; }
void g() { assert(v == sure); }
---
I also store a copy of `s` into `sure` for my friend to ensure
immutable
date hasn't been mutated.
Can my friend's assertion ever fail without breaking a type-system?
Sure. Just consider this:
---
void main() {
auto s = "abba".idup;
    f(s);
    delete s;
    g();
}
---
Is it by-design? Looks like deleting immutable (and const because of
implicit conversion) data should be prohibited.
OK. Let `delete` be fixed. Can we still fail?
---
void h() {
    immutable(char)[4] s = "abba";
    f(s);
}
void main() {
    h();
    g();
}
---
Damn! So, what can we do with it? Not sure, but I have a proposal.

Fix it in language:
* disallow `delete` of const/immutable data
* disallow immutable data on the stack

This makes data really immutable if I don't miss something. Anyway, I
want `immutable` qualified data to be immutable without breaking a
type-system (if one do it, its his own responsibility), so some changes
should be made (IMHO).

You are using unsafe language features to break the type system. That is
not the fault of the type system.

'@safe:' at the top of the program should stop both examples from
working, it is a bug that it does not.

That's the point -- *which* checks are missing from @safe?

Escaping stack data and arbitrarily freeing memory are not operations
found in memory safe languages.

HOW do you propose to check for escaping stack data?

But I'm not sure that you're right, this looks broken to me, even
without @safe.

What does it mean to create immutable data on the stack? The stack is
intrinsically mutable!

So is the heap.

No it is not. Data on the stack *cannot* survive past the end of the function call. Data on the heap can last forever.

What does it mean to garbage collect immutable data?

From the point of view of the application, it doesn't happen. There are no observable semantics. It's merely an implementation detail.

What does it mean to allocate an 'int' on the stack?

What does it mean to delete immutable data?

Deallocate the storage for it and make it available for reuse.
Accessing it afterwards leads to arbitrary behaviour. This is the same
with mutable data. As the program may behave arbitrarily in this case,
it is valid behaviour to act as if immutable data changed.

No, you've broken the type system if you've deleted immutable data.
If I have a reference to an immutable variable, I have a guarantee that it will never change. delete will break that guarantee.

With a mutable variable, I have no such guarantee. (It's not safe to allocate something different in the deleted location, but it's OK to run the finalizer and then wipe all the memory).

I think it's reasonable for both of them to require a cast, even in
@system code.


The implementation of the 'scope' storage class should be fixed. We
could then require an unsafe cast(scope) to disable prevention of stack
address escaping.

No we can't. f cannot know that the string it has been given is on the stack. So main() must prevent it from being given to f() in the first place. How can it do that?

void foo(bool b, string y)
{
  immutable (char)[4] x = "abba";
  string s = b ? x : y;
  f(s);
}

Make it safe.


Rust's borrowed pointers may give some hints on how
to extend 'scope' to fields of structs.

I think it is more fundamental than that.

As to delete, delete is as unsafe when the involved data is immutable
as when it is mutable. Why require an additional cast in one case?

This is not about safety.
Modifying immutable data breaks the type system. Deleting mutable data does not. AFAIK it is safe to implement delete as a call to the finalizer, followed by setting the memory to T.init. Only the GC can determine if it is safe to reuse the memory.

Deleting immutable data just doesn't make sense.

Reply via email to