Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTracking issue for CString::{from_ptr, into_ptr} #27769
Comments
alexcrichton
added
T-libs
B-unstable
E-easy
final-comment-period
labels
Aug 12, 2015
This comment has been minimized.
This comment has been minimized.
|
This feature is now entering its final comment period for stabilization. I will post a PR soon for renaming these function to |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Aug 14, 2015
alexcrichton
referenced this issue
Aug 14, 2015
Merged
std: Rename `cstr_memory` feature to use "raw" #27836
This comment has been minimized.
This comment has been minimized.
Awesome! That makes sense to me. |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Aug 16, 2015
This comment has been minimized.
This comment has been minimized.
|
This rename is important because |
This comment has been minimized.
This comment has been minimized.
|
If you use |
This comment has been minimized.
This comment has been minimized.
|
We need to learn from these bugs. Premature dropping of |
ashleysommer
referenced this issue
Aug 18, 2015
Closed
Segfault in je_rallocx after pushing new value to Vec<u8> causing it to resize #27878
This comment has been minimized.
This comment has been minimized.
|
@bluss an interesting question. In my mind, once you hit a raw pointer, all bets are off and you have to manage everything yourself. Do you have any thoughts on how to improve that with types? |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Aug 18, 2015
bors
added a commit
that referenced
this issue
Aug 18, 2015
This comment has been minimized.
This comment has been minimized.
|
You can still get some type-safety with raw pointers, though you don't get ownership tracking. I can see a potential API along these lines: #[repr(i8)] enum RustAllocChar {...}
impl CString {
fn into_raw(self) -> *const RustAllocChar;
unsafe fn from_raw(ptr: *const RustAllocChar) -> CString;
}which lets you write something like extern {
fn do_stuff(string: *mut RustAllocChar, free: fn(*mut RustAllocChar));
}
extern fn free(ptr: *mut RustAllocChar) {
drop(CString::from_raw(ptr));
}
fn main() {
let s = CString::new("Hello!").unwrap();
unsafe {do_stuff(s.into_raw(), free)};
}or for a library #[no_mangle] // char *mylib_do_stuff(void);
extern fn mylib_do_stuff() -> *mut RustOwnedChar {...}
#[no_mangle] // void mylib_free(char *s);
extern fn mylib_free(s: *mut RustOwnedChar) {...}So |
This comment has been minimized.
This comment has been minimized.
|
Also, while I was writing the above, I realized -- shouldn't Similarly, [EDIT: |
This comment has been minimized.
This comment has been minimized.
I disagree. There's no reason to assume that a
The problem is that we are dealing with C /FFI and these types are indistinguishable. I think that the additional cognitive overhead of having to remember that a It also sound like you are trying to use these methods inside of Rust code to call FFI code. That's definitely not the intended use case, as you don't want to have a one-way transfer of ownership due to the reallocation requirements.
That's a good reason to change them, and it was probably a mistake on my part originally. Honestly, the fluidity of |
This comment has been minimized.
This comment has been minimized.
Maybe I was unclear, but this depends specifically on annotating types with a Obviously this requires defining the FFI interfaces to use these types when appropriate, and not use them when inappropriate. I don't think that's too hard (we just need to pick a less stupid name than the ones I've come up with). To be fair, it is confusing that I'm distinguishing the type of the pointed-to thing, not the type of the pointer, when it is semantically a different sort of (raw) pointer to the same
I'm not clear on when you'd need to coerce it, in Rust code. The only purpose of a
Yeah, drop my first example with the callback because that's more confusing than it's worth. What I have in mind is implementing a C API contract that says something like, "This function returns a pointer. When you are done with it, free it by calling this other function," as you would do if you were implementing a C-ABI plugin spec, or writing a C-ABI library in Rust. Your example from #25777 does this. If I added both proper #[no_mangle]
pub extern fn reverse(s: *const libc::c_char) -> *mut RustAllocChar {
let s = unsafe { CStr::from_ptr(s) };
let s2 = s.to_str().unwrap();
let s3: String = s2.chars().rev().collect();
let s4 = CString::new(s3).unwrap();
s4.into_ptr()
}
#[no_mangle]
pub extern fn cleanup(s: *mut RustAllocChar) {
unsafe { CString::from_ptr(s) };
}#include <stdio.h>
extern char *reverse(const char *);
extern void cleanup(char *);
int main() {
char *s = reverse("Hello, world!");
printf("%s\n", s);
cleanup(s);
}which, at least on the Rust side, makes it clear what pointers are owned and which are borrowed. On the C side, the API docs or header files would probably have a comment on
Only when you're defining the FFI. Rust requires you to do an unsafe cast to turn Incidentally, the fact that C literals have type |
This comment has been minimized.
This comment has been minimized.
|
I agree with changing In general I feel the extra cognitive overhead of having an extra type just for this return value may not be worth the little bit of extra safety we get. For example there's still the case where |
This comment has been minimized.
This comment has been minimized.
... sigh, yes, you're right. OK, I withdraw that. So if the answer is that there's no practical way to increase the type-safety of these functions, that's fine. And |
alexcrichton
added a commit
to alexcrichton/rust
that referenced
this issue
Sep 3, 2015
alexcrichton
referenced this issue
Sep 3, 2015
Merged
std: Update CString::{into,from}_raw with `*mut T` #28198
bors
added a commit
that referenced
this issue
Sep 9, 2015
This comment has been minimized.
This comment has been minimized.
|
@Gankro Some of the above discussion makes me think about your plans with |
alexcrichton commentedAug 12, 2015
This is a tracking issue for the unstable
cstr_memoryfeature in the standard library. These methods are likely ready to go as-is modulo naming. Their names should be consistent withBox::{from_raw, into_raw}(currently inconsistent).cc #27768