What exactly does "@safe" mean?

Jonathan M Davis jmdavisProg at gmx.com
Sat Jun 1 15:14:46 PDT 2013


On Saturday, June 01, 2013 23:41:32 monarch_dodra wrote:
> On Saturday, 1 June 2013 at 21:02:44 UTC, Jonathan M Davis wrote:
> > On Saturday, June 01, 2013 21:59:18 monarch_dodra wrote:
> >> The way I understood it, @safe defines a list of things that
> >> are
> >> or aren't legal inside the implementation of a function. It
> >> also
> >> changes the scheme of bounds checking, in release code.
> >> 
> >> What bothers me though, is that from an interface point of
> >> view,
> >> it doesn't really mean anything (or at least, I haven't really
> >> understood anything). AFAIK: if I call something "@safe",
> >> chances
> >> of a core dump are relatively "lower", but they can still
> >> happen:
> >> * A function that accepts a pointer as an argument can be
> >> marked
> >> safe, so all bets are off there, no, since the pointer can be
> >> dereferenced?
> >> * Member functions for structs that have pointers, too, can be
> >> marked safe...
> >> 
> >> Or does it only mean "if you give me valid pointers, I can't
> >> core
> >> dump*"?
> >> (*ignoring current flaws, such as escaping slices from static
> >> arrays)
> >> 
> >> The main reason about this question is that now I'm confused
> >> about @trusted: what are the conditions a developer needs to
> >> take
> >> into account before marking a function "@trusted" ?
> >> 
> >> Ditto for member functions, when they operate on pointer
> >> members.
> >> Can those be @safe?
> >> 
> >> Yeah, overall, I'm confused as to what "@safe" means from an
> >> interface point of view :(
> > 
> > @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.
> > 
> > Assuming that there are no bugs in @safe, the one thing that
> > can invalidate it
> > is @trusted. With @trusted code, it is the _programmer_ who is
> > then
> > guaranteeing that the code is actually @safe. The code is doing
> > something
> > which is potentially not safe (and therefore is considered
> > @system by the
> > compiler) but which _could_ be safe if the code is correct, and
> > if the
> > programmer is marking the code as @trusted, they are then
> > telling the compiler
> > that they've verified that the code isn't doing anything which
> > could corrupt
> > memory. As long as the programmer doesn't screw that up, then
> > any @safe code
> > calling that @trusted function is indeed @safe, but if the
> > programmer screwed
> > it up, then you could still get memory corruption. However,
> > here's really no
> > way to get around that problem with a systems language, since
> > most code needs
> > to eventually call something that's @system (e.g. all I/O needs
> > @system stuff
> > internally). But by limiting how much code is @system or
> > @trusted, most code
> > is @safe with a minimal amount of code having to have been
> > verified by an
> > appropriately competent programmer as being @trusted.
> > 
> > - Jonathan M Davis
> 
> OK. But by that standard, can't (mostly) anything be trusted?
> What about something that writes garbage, to a memory location it
> was *asked* to write to? Or if wrong usage of the function can
> lead to an inconsistence memory state, but without "out of bounds
> accesses"?

When a programmer marks a function as @trusted, they are saying that they 
guarantee that the function will not do anything to corrupt memory. So, yes, a 
programmer could mark absolutely anything as @trusted - including stuff that is 
blatantly unsafe and will do all kinds of nasty stuff - but that's the 
programmer's fault. The compiler told them that it was @system and therefore 
could not be verified to be memory safe, and the programmer insisted that it 
was memory safe.

Any code which cannot be guaranteed to be actually safe should not be marked 
with @trusted. It's up to the programmer figure out whether what they're doing 
is valid or not.

> For instance: "emplace!T(T* p)": This function takes the address
> of a T, and writes T.init over it. It does a memcopy, so it can't
> be @safe, but I can 100% guarantee I'm not doing anything wrong,
> so I'm marking it as @trusted. This should be fine, right? Or is
> raw memory copying alway unsafe?

Raw memory copying should be fine as long as the memory being copied from and 
the memory being copied to is valid.

> Now, technically, emplace can't be called in @safe code, since it
> requires a pointer to begin with.

Pointers can be in @safe code. They're perfectly safe in and of themselves. 
It's certain operations on pointers which are unsafe (such as pointer 
arithmetic).

> But still, if I were to give emplace an "already constructed
> object", it will happily clobber that object for me, leaking the
> destructor, and possibly putting the program in an invalid memory
> state.
> 
> Now, it was *my* fault for calling emplace with an already built
> object, but it was the (@trusted) emplace that clobbered-it.

Well, given that the safety of the operation relies on what's being passed in, 
the operation itself can't reasonably be marked as @safe, because you can't 
guarantee that the operation isn't going to corrupt memory.

- Jonathan M Davis


More information about the Digitalmars-d mailing list