Using Rust’s Foreign Function Interface (FFI) with C! (Part one of several about FFI!)
Using Rust’s Foreign Function Interface (FFI) with C! (Part one of several about FFI!)
Great episode, as always! ![]()
Just a small note: when you talk about the fact that C can do whatever it wants, it is not true that 'point' can be changed... at least not the value we passed to the FFI function. In other words, C does not have the concept of references (like C++), therefore 'point' is a Point * by value. The function can change it, but this will not any visible behaviour from the caller point of view. As a consequence, Point * const in a function declaration is useful for the maintainer of the function to avoid erroneous changes to the pointer (not the Point itself) , nothing more.
Oh, excellent correction. Clearly my C is rusty (no pun intended!). Thank you!
Here are examples of writing to the 4 permutations of constness of pointer vs referent,
annotated with compile-time errors:
In C:
#include <stdio.h>
/*
No errors
*/
void func0(int* foo){
*foo=10;
foo=NULL;
}
/*
foo.c: In function ‘func1’:
foo.c:12:8: error: assignment of read-only parameter ‘foo’
foo=NULL;
^
*/
void func1(int*const foo){
*foo=10;
foo=NULL;
}
/*
foo.c: In function ‘func2’:
foo.c:22:9: error: assignment of read-only location ‘*foo’
*foo=10;
^
*/
void func2(const int* foo){
*foo=10;
foo=NULL;
}
/*
foo.c: In function ‘func3’:
foo.c:37:9: error: assignment of read-only location ‘*foo’
*foo=10;
^
foo.c:38:8: error: assignment of read-only parameter ‘foo’
foo=NULL;
^
*/
void func3(const int*const foo){
*foo=10;
foo=NULL;
}
int main(){
return 0;
}
In Rust:
use std::ptr;
/*
No errors
*/
fn func0(mut foo:*mut i32){
unsafe{
*foo=10;
foo=ptr::null_mut();
}
}
/*
error[E0384]: cannot assign to immutable argument `foo`
--> src/lib.rs:7:9
|
4 | fn func1(foo:*mut i32){
| --- help: make this binding mutable: `mut foo`
...
7 | foo=ptr::null_mut();
| ^^^^^^^^^^^^^^^^^^^ cannot assign to immutable argument
*/
fn func1(foo:*mut i32){
unsafe{
*foo=10;
foo=ptr::null_mut();
}
}
/*
error[E0594]: cannot assign to `*foo` which is behind a `*const` pointer
--> src/lib.rs:13:9
|
11 | fn func2(mut foo:*const i32){
| ---------- help: consider changing this to be a mutable pointer: `*mut i32`
12 | unsafe{
13 | *foo=10;
| ^^^^^^^ `foo` is a `*const` pointer, so the data it refers to cannot be written
*/
fn func2(mut foo:*const i32){
unsafe{
*foo=10;
foo=ptr::null();
}
}
/*
error[E0594]: cannot assign to `*foo` which is behind a `*const` pointer
--> src/lib.rs:20:9
|
18 | fn func3(foo:*const i32){
| ---------- help: consider changing this to be a mutable pointer: `*mut i32`
19 | unsafe{
20 | *foo=10;
| ^^^^^^^ `foo` is a `*const` pointer, so the data it refers to cannot be written
error[E0384]: cannot assign to immutable argument `foo`
--> src/lib.rs:21:9
|
18 | fn func3(foo:*const i32){
| --- help: make this binding mutable: `mut foo`
...
21 | foo=ptr::null();
| ^^^^^^^^^^^^^^^ cannot assign to immutable argument
*/
fn func3(foo:*const i32){
unsafe{
*foo=10;
foo=ptr::null();
}
}
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.