On Tuesday, 7 July 2015 at 20:23:08 UTC, H. S. Teoh wrote:
The reason for this is that function pointers have attributes
associated with them, as part of the type system. The address
of a @safe function is a @safe function pointer, meaning that
it's legal to call the function through this pointer in @safe
code. The address of a @system function is a @system function
pointer, which *cannot* be used to call the function from @safe
code.
However, while it is not allowed to assign a @system function
pointer to a @safe function pointer (since that could be used
to bypass the @safe restriction on calling @system functions),
it is OK to assign a @safe function pointer to a @system
function pointer (this is called covariance). This is allowed
because a @system function pointer can only be dereferenced in
@system code, and @system code can freely call any function
with no restrictions. Where this might become a problem,
though, is when you inadvertently assign a @safe function
pointer to a @system function pointer, and then attempt to call
it from @safe code -- the compiler will reject that. This is
what happened with your sample code:
This, and the rest, does such a good job explaining why I have
been so confused.
Either that, or use `auto` to let the compiler figure out the
correct function pointer attributes for you:
auto fp = &cbrt;
pragma(msg, typeof(fp).stringof);
I've tried using auto, but I get errors when I use auto with a
function that has been overloaded. For instance,
creal function(creal) pure nothrow @nogc @safe fp = &conj;
compiles, but
auto fp = &conj;
does not.