-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rust 1.78 Does Not Return c_void Pointer Correctly #125658
Comments
Since passing an extern {
fn initialize_wrapper(result: *mut i32) -> *mut c_void;
}
...
let mut result: i32 = 0;
let context = unsafe { initialize_wrapper(&mut result) };
// check result
...
// pass context to another C function |
extern {
fn initialize(ctx: &*mut c_void) -> i32;
} That looks like UB because your passing a shared reference rather than a mutable one. I.e. it should be defined as: extern {
fn initialize(ctx: &mut *mut c_void) -> i32;
} |
It's just odd that it worked up to 1.77.0 and also with 1.78.0, there are still some weird conditions where it still works (see description). |
I believe that what you're trying to do is UB, by taking an immutable reference and trying to assign to it you're violating the immutability requirements of that reference. At least that's what I think is happening when I try to recreate your sample code in pure Rust, playground. Using a mutable reference should already be a step in the right direction. extern {
fn initialize(ctx: &mut *mut c_void) -> i32;
}
// ...
let mut context = ptr::null_mut();
let result = unsafe { initialize(&mut context) }; |
Optimization around aliasing are (if I remember correctly) only done at higher level of optimization. |
Thanks, using the |
the compiler usually doesn't complain about doing undefined behavior because it doesn't know that you're doing undefined behavior. |
here the compiler just assumed that you wouldn't modify it, and it has no way of knowing that you are modifying it. you just have to be careful. i don't think there's a tool that could have helped in this case, but in general, make sure to use tools like address sanitizer to check your unsafe code (and for unsafe code without FFI, Miri). closing as not a bug |
We need to use a C library/API that has an initialization routine that returns a new opaque pointer in a parameter (i.e.
func(void** ctx)
). To do so, we have an interface similar to this:This has always worked since at least version 1.64.0. Recently, we started seeing our Windows build failing. Debugging reveals that since 1.78.0, variable
context
is always 0 and does not receive the pointer value created by the C function.Further debugging shows the following:
--release
Version it worked on
It most recently worked on: 1.77
Version with regression
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: