What is the "Raw" Value of an Owned Type?

So if you have a function pointer like fn(&mut T), the argument is a reference, aka. a pointer that could be also represented as fn(*const u8) and have the same ABI, correct? This allows me to represent the function ABI without knowing T's concrete type.

But if I have a function like fn() -> T what is the type of T in it's most "raw" form. Is there an equivalent function pointer similar to the example above that doesn't need to know the type of T? For instance I can't do fn() -> *const u8 because T isn't a pointer, it's an owned type.

No, there's no function pointer that can represent any return type.

1 Like

OK, then I should be able to get around it by making the function signature fn() -> *mut u8 and return a reference that I've leaked out of a Box and then later re-claim it by using Box::from_raw.

Or you can just require that every function take a pointer-to-return-value address in their first argument, and have the functions fill that space that you allocate beforehand in the caller's stack frame.

2 Likes

Oh, so instead of returning a value, it would write data to a pointer that is passed as an argument.

I think I like that, that should work, thanks!

I'm pretty sure that the ABIs of fn(&mut T) and fn(*mut T) aren't guaranteed to be the same, because basically nothing is guaranteed for extern "Rust" fn. (At the very minimum, you need to make sure T is Sized.)

If you need to be able to treat function pointers opaquely like this, you either need adaptor closures or extern "C".

2 Likes

Would that be true even in the same binary? In my case I'm actually just casting/transmuting the function pointers so do you think that fn(&mut T) as fn(*mut T) ( pseudocode ) would not necessarily be valid?

Edit: Oh, wait, I just found a way around having to use that cast anyway, so it shouldn't matter.

If you are trying to make a generalized calling convention for a JIT or something like libffi or Python's ctypes, then you are probably better off declaring such function pointers as extern "C" and making them accept raw pointers instead of references. While this will make calling them unsafe, they will have a stable ABI that you can rely on.

1 Like