On Saturday, June 01, 2013 23:34:09 Peter Alexander wrote:
> On Saturday, 1 June 2013 at 21:02:44 UTC, Jonathan M Davis wrote:
> > @safe is for memory safety, meaning that @safe code cannot
> > corrupt memory. You
> > can get segfaults due to null pointers and the like, but you
> > can't have code
> > which writes passed the end of a buffer, or which uses a freed
> > memory, or does
> > anything else which involves writing or reading from memory
> > which variables
> > aren't supposed to have access to.
> 
> Not true.
> 
> void foo(int* p) @safe
> {
>       *p = 0;
> }
> 
> void main()
> {
>       int[3] buf1 = [1, 2, 3];
>       int[1] buf2;
>       int* p = buf2.ptr;
>       --p;
>       foo(p);
>       import std.stdio;
>       writeln(buf1);
> }
> 
> For me, this prints [1, 2, 0]. You could easily come up with an
> example which writes to freed memory.
> 
> You can argue that foo didn't "cause" this problem (the undefined
> behaviour from the pointer arithmetic in main did), but that's
> irrelevant: what guarantees do I have when I call a @safe
> function that I don't have with any non-@safe function?
> 
> Do @safe functions only provide guarantees when the inputs are
> valid, or is it the case the @safe functions are guaranteed to
> not *introduce* any new undefined behaviour?

They're guaranteed to not introduce any such behavior. They can't possibly 
make any guarantees if the caller did @system operations and passed a bad 
pointer to the @safe function. But if all of the functions in the call stack 
are @safe, and you call an @safe function, then you can't get any memory 
corruption unless it (or a function that it calls) calls an @trusted function 
which was incorrectly verified by the programmer who marked it as @trusted.

- Jonathan M Davis

Reply via email to