6

Both in ffi tutorials and in automatically generated interfaces, *const T pointers are used most of the time. As far as I know the difference between &T and *const T is only that *const T doesn't have to fulfill certain conditions like not being null and is unsafe to dereference.

fn main() {
    unsafe {
        do_something(&TestStruct {data: 3})
    }
}

#[repr(C)]
pub struct TestStruct {
    data: u32
}

extern "C" {
    fn do_something(arg: &TestStruct);
}

This code can be compiled and runs. Because external functions are similar in usage to internal ones, i don't understand why raw pointers are used there as the default.

Herohtar
  • 5,347
  • 4
  • 31
  • 41
Goldenprime
  • 324
  • 1
  • 10

1 Answers1

2

An element of answer can probably be found in the fact that references must be aligned. As using un-aligned references is undefined behaviour, and the alignment of the pointers cannot be guaranteed in FFIs, defaulting to pointers seems to be a sane choice

Magix
  • 4,989
  • 7
  • 26
  • 50
  • That makes sense, but wouldn't that then only apply to pointers returned from the external function. The external function takes as argument a pointer that does not have to be aligned, a reference is aligned, but that is not a problem for the c code on the other side. The problem only arises when a non-aligned pointer is returned from the external function and then interpreted as a reference. – Goldenprime Apr 05 '22 at 10:28
  • 4
    another point is that if a value is borrowed immutably it is guaranteed by the compiler not to change. However when passing pointers (even immutable ones) into ffi function such guarantees are impossible, because of how easy it is to mutate data in C/C++ for example – gmoshkin Apr 05 '22 at 11:30