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