Skip to content

Replace c_str.with_ref(...) with .as_ptr() #14904

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

Merged
merged 3 commits into from
Jun 29, 2014

Conversation

huonw
Copy link
Member

@huonw huonw commented Jun 14, 2014

No description provided.

@alexcrichton
Copy link
Member

I believe that this was explicitly not done before due to the hazards of invoking as_ptr. I have seen code similarly to this recently, which is often difficult to debug:

fn foo(s: &str) -> *c_char { 
    s.to_c_str().as_ptr() 
}

That is an example behind the reasoning of the initial decision. I, however, prefer as_ptr() to with_ref(). RAII is much more common than it when the c_str module was written. This probably warrants some discussion, however, to revert the explicit original decision to not include this function.

Stylistically, could you add some comments to the dangers of dealing with the return value of as_ptr?

@huonw
Copy link
Member Author

huonw commented Jun 16, 2014

That's a good point. Will do!

I wonder if it we could assist by having a lint like #[must_use], something like

#[returns_internal_raw_pointer]
fn as_ptr(&self) -> *c_char { ... }

let p = x.to_c_str().as_ptr(); // warning: internal raw pointer may be invalidated at the end of this statement

However, I'm not sure when else this would be useful so may be pointless.

@huonw
Copy link
Member Author

huonw commented Jun 19, 2014

r? @alexcrichton (added docs and expanded the first commit message)

huonw added 3 commits June 29, 2014 21:15
These forms return the pointer directly, rather than the added
indirection, indentation, and inefficiencies of the closures in
`.with_ref` and `.with_mut_ref`. The two closure functions are
deprecated.

Replace

    foo(c_str.with_ref(|p| p))

    c_str.with_ref(|p| {
        foo(p);
        bar(p);
    })

with

    foo(c_str.as_ptr())

    let p = c_str.as_ptr();
    foo(p);
    bar(p);

This change does mean that one has to be careful to avoid writing `let p
= x.to_c_str().as_ptr();` since the `CString` will be freed at the end
of the statement. Previously, `with_ref` was used (and `as_ptr` avoided)
for this reason, but Rust has strongly moved away from closures to more
RAII-style code, and most uses of `.with_ref` where in the form
`.with_ref(|p| p)` anyway, that is, they were exactly `.as_ptr`.

[breaking-change]
This should be called rarely, but it was placed first in the list of
methods, making it very tempting to call.
@bors bors closed this Jun 29, 2014
@bors bors merged commit 569f13a into rust-lang:master Jun 29, 2014
@mvdnes
Copy link
Contributor

mvdnes commented Jun 30, 2014

I was wondering if the as_ptr() should be unsafe? I know that to use the result, an unsafe block is needed. However, this way a bug such as calling let p = x.to_c_str().as_ptr() may occur outside of an unsafe block, and thus will be harder to find.

@huonw huonw deleted the cstr-remove-withref branch July 11, 2014 05:54
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 5, 2023
Render size, align and offset hover values in hex

Arguably, these values are usually almost always viewed in hex format so I think we should do the same here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants