Skip to content

Commit 8da694a

Browse files
Overhaul the ffi::CString docs
Explain the struct's reason for being, and its most common usage patterns. Add a bunch of links. Clarify the method docs a bit. Part of #29354
1 parent 5451b72 commit 8da694a

File tree

1 file changed

+115
-31
lines changed

1 file changed

+115
-31
lines changed

src/libstd/ffi/c_str.rs

Lines changed: 115 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,68 @@ use ptr;
2323
use slice;
2424
use str::{self, Utf8Error};
2525

26-
/// A type representing an owned C-compatible string.
26+
/// A type representing an owned, C-compatible, UTF-8 string.
2727
///
28-
/// This type serves the primary purpose of being able to safely generate a
29-
/// C-compatible string from a Rust byte slice or vector. An instance of this
28+
/// This type serves the purpose of being able to safely generate a
29+
/// C-compatible UTF-8 string from a Rust byte slice or vector. An instance of this
3030
/// type is a static guarantee that the underlying bytes contain no interior 0
31-
/// bytes and the final byte is 0.
31+
/// bytes ("nul characters") and that the final byte is 0 ("nul terminator").
3232
///
33-
/// A `CString` is created from either a byte slice or a byte vector. A [`u8`]
34-
/// slice can be obtained with the `as_bytes` method. Slices produced from a
35-
/// `CString` do *not* contain the trailing nul terminator unless otherwise
36-
/// specified.
33+
/// `CString` is to [`CStr`] as [`String`] is to [`&str`]: the former
34+
/// in each pair are owned strings; the latter are borrowed
35+
/// references.
3736
///
37+
/// # Creating a `CString`
38+
///
39+
/// A `CString` is created from either a byte slice or a byte vector,
40+
/// or anything that implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>` (for
41+
/// example, you can build a `CString` straight out of a [`String`] or
42+
/// a [`&str`], since both implement that trait).
43+
///
44+
/// The [`new`] method will actually check that the provided `&[u8]`
45+
/// does not have 0 bytes in the middle, and return an error if it
46+
/// finds one.
47+
///
48+
/// # Extracting a raw pointer to the whole C string
49+
///
50+
/// `CString` implements a [`as_ptr`] method through the [`Deref`]
51+
/// trait. This method will give you a `*const c_char` which you can
52+
/// feed directly to extern functions that expect a nul-terminated
53+
/// string, like C's `strdup()`.
54+
///
55+
/// # Extracting a slice of the whole C string
56+
///
57+
/// Alternatively, you can obtain a `&[`[`u8`]`]` slice from a
58+
/// `CString` with the [`as_bytes`] method. Slices produced in this
59+
/// way do *not* contain the trailing nul terminator. This is useful
60+
/// when you will be calling an extern function that takes a `*const
61+
/// u8` argument which is not necessarily nul-terminated, plus another
62+
/// argument with the length of the string — like C's `strndup()`.
63+
/// You can of course get the slice's length with its
64+
/// [`len`][slice.len] method.
65+
///
66+
/// If you need a `&[`[`u8`]`]` slice *with* the nul terminator, you
67+
/// can use [`as_bytes_with_nul`] instead.
68+
///
69+
/// Once you have the kind of slice you need (with or without a nul
70+
/// terminator), you can call the slice's own
71+
/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to
72+
/// extern functions. See the documentation for that function for a
73+
/// discussion on ensuring the lifetime of the raw pointer.
74+
///
75+
/// [`Into`]: ../convert/trait.Into.html
76+
/// [`Vec`]: ../vec/struct.Vec.html
77+
/// [`String`]: ../string/struct.String.html
78+
/// [`&str`]: ../primitive.str.html
3879
/// [`u8`]: ../primitive.u8.html
80+
/// [`new`]: #method.new
81+
/// [`as_bytes`]: #method.as_bytes
82+
/// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
83+
/// [`as_ptr`]: #method.as_ptr
84+
/// [slice.as_ptr]: ../primitive.slice.html#method.as_ptr
85+
/// [slice.len]: ../primitive.slice.html#method.len
86+
/// [`Deref`]: ../ops/trait.Deref.html
87+
/// [`CStr`]: struct.CStr.html
3988
///
4089
/// # Examples
4190
///
@@ -48,6 +97,8 @@ use str::{self, Utf8Error};
4897
/// fn my_printer(s: *const c_char);
4998
/// }
5099
///
100+
/// // We are certain that our string doesn't have 0 bytes in the middle,
101+
/// // so we can .unwrap()
51102
/// let c_to_print = CString::new("Hello, world!").unwrap();
52103
/// unsafe {
53104
/// my_printer(c_to_print.as_ptr());
@@ -58,7 +109,7 @@ use str::{self, Utf8Error};
58109
/// # Safety
59110
///
60111
/// `CString` is intended for working with traditional C-style strings
61-
/// (a sequence of non-null bytes terminated by a single null byte); the
112+
/// (a sequence of non-nul bytes terminated by a single nul byte); the
62113
/// primary use case for these kinds of strings is interoperating with C-like
63114
/// code. Often you will need to transfer ownership to/from that external
64115
/// code. It is strongly recommended that you thoroughly read through the
@@ -215,8 +266,11 @@ pub struct IntoStringError {
215266
impl CString {
216267
/// Creates a new C-compatible string from a container of bytes.
217268
///
218-
/// This method will consume the provided data and use the underlying bytes
219-
/// to construct a new string, ensuring that there is a trailing 0 byte.
269+
/// This method will consume the provided data and use the
270+
/// underlying bytes to construct a new string, ensuring that
271+
/// there is a trailing 0 byte. This trailing 0 byte will be
272+
/// appended by this method; the provided data should *not*
273+
/// contain any 0 bytes in it.
220274
///
221275
/// # Examples
222276
///
@@ -234,9 +288,11 @@ impl CString {
234288
///
235289
/// # Errors
236290
///
237-
/// This function will return an error if the bytes yielded contain an
238-
/// internal 0 byte. The error returned will contain the bytes as well as
291+
/// This function will return an error if the supplied bytes contain an
292+
/// internal 0 byte. The [`NulError`] returned will contain the bytes as well as
239293
/// the position of the nul byte.
294+
///
295+
/// [`NulError`]: struct.NulError.html
240296
#[stable(feature = "rust1", since = "1.0.0")]
241297
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
242298
Self::_new(t.into())
@@ -249,8 +305,8 @@ impl CString {
249305
}
250306
}
251307

252-
/// Creates a C-compatible string from a byte vector without checking for
253-
/// interior 0 bytes.
308+
/// Creates a C-compatible string by consuming a byte vector,
309+
/// without checking for interior 0 bytes.
254310
///
255311
/// This method is equivalent to [`new`] except that no runtime assertion
256312
/// is made that `v` contains no 0 bytes, and it requires an actual
@@ -275,7 +331,7 @@ impl CString {
275331
CString { inner: v.into_boxed_slice() }
276332
}
277333

278-
/// Retakes ownership of a `CString` that was transferred to C.
334+
/// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
279335
///
280336
/// Additionally, the length of the string will be recalculated from the pointer.
281337
///
@@ -286,7 +342,14 @@ impl CString {
286342
/// ownership of a string that was allocated by foreign code) is likely to lead
287343
/// to undefined behavior or allocator corruption.
288344
///
345+
/// > **Note:** If you need to borrow a string that was allocated by
346+
/// > foreign code, use [`CStr`]. If you need to take ownership of
347+
/// > a string that was allocated by foreign code, you will need to
348+
/// > make your own provisions for freeing it appropriately, likely
349+
/// > with the foreign code's API to do that.
350+
///
289351
/// [`into_raw`]: #method.into_raw
352+
/// [`CStr`]: struct.CStr.html
290353
///
291354
/// # Examples
292355
///
@@ -315,11 +378,11 @@ impl CString {
315378
CString { inner: mem::transmute(slice) }
316379
}
317380

318-
/// Transfers ownership of the string to a C caller.
381+
/// Consumes the `CString` and transfers ownership of the string to a C caller.
319382
///
320-
/// The pointer must be returned to Rust and reconstituted using
383+
/// The pointer which this function returns must be returned to Rust and reconstituted using
321384
/// [`from_raw`] to be properly deallocated. Specifically, one
322-
/// should *not* use the standard C `free` function to deallocate
385+
/// should *not* use the standard C `free()` function to deallocate
323386
/// this string.
324387
///
325388
/// Failure to call [`from_raw`] will lead to a memory leak.
@@ -356,6 +419,22 @@ impl CString {
356419
/// On failure, ownership of the original `CString` is returned.
357420
///
358421
/// [`String`]: ../string/struct.String.html
422+
///
423+
/// # Examples
424+
///
425+
/// ```
426+
/// use std::ffi::CString;
427+
///
428+
/// let valid_utf8 = vec![b'f', b'o', b'o'];
429+
/// let cstring = CString::new(valid_utf8).unwrap();
430+
/// assert_eq!(cstring.into_string().unwrap(), "foo");
431+
///
432+
/// let invalid_utf8 = vec![b'f', 0xff, b'o', b'o'];
433+
/// let cstring = CString::new(invalid_utf8).unwrap();
434+
/// let err = cstring.into_string().err().unwrap();
435+
/// assert_eq!(err.utf8_error().valid_up_to(), 1);
436+
/// ```
437+
359438
#[stable(feature = "cstring_into", since = "1.7.0")]
360439
pub fn into_string(self) -> Result<String, IntoStringError> {
361440
String::from_utf8(self.into_bytes())
@@ -365,10 +444,11 @@ impl CString {
365444
})
366445
}
367446

368-
/// Returns the underlying byte buffer.
447+
/// Consumes the `CString` and returns the underlying byte buffer.
369448
///
370-
/// The returned buffer does **not** contain the trailing nul separator and
371-
/// it is guaranteed to not have any interior nul bytes.
449+
/// The returned buffer does **not** contain the trailing nul
450+
/// terminator, and it is guaranteed to not have any interior nul
451+
/// bytes.
372452
///
373453
/// # Examples
374454
///
@@ -388,7 +468,7 @@ impl CString {
388468
}
389469

390470
/// Equivalent to the [`into_bytes`] function except that the returned vector
391-
/// includes the trailing nul byte.
471+
/// includes the trailing nul terminator.
392472
///
393473
/// [`into_bytes`]: #method.into_bytes
394474
///
@@ -408,8 +488,12 @@ impl CString {
408488

409489
/// Returns the contents of this `CString` as a slice of bytes.
410490
///
411-
/// The returned slice does **not** contain the trailing nul separator and
412-
/// it is guaranteed to not have any interior nul bytes.
491+
/// The returned slice does **not** contain the trailing nul
492+
/// terminator, and it is guaranteed to not have any interior nul
493+
/// bytes. If you need the nul terminator, use
494+
/// [`as_bytes_with_nul`] instead.
495+
///
496+
/// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
413497
///
414498
/// # Examples
415499
///
@@ -427,7 +511,7 @@ impl CString {
427511
}
428512

429513
/// Equivalent to the [`as_bytes`] function except that the returned slice
430-
/// includes the trailing nul byte.
514+
/// includes the trailing nul terminator.
431515
///
432516
/// [`as_bytes`]: #method.as_bytes
433517
///
@@ -598,8 +682,8 @@ impl Default for Box<CStr> {
598682
}
599683

600684
impl NulError {
601-
/// Returns the position of the nul byte in the slice that was provided to
602-
/// [`CString::new`].
685+
/// Returns the position of the nul byte in the slice that caused
686+
/// [`CString::new`] to fail.
603687
///
604688
/// [`CString::new`]: struct.CString.html#method.new
605689
///
@@ -766,7 +850,7 @@ impl CStr {
766850
/// assert!(cstr.is_ok());
767851
/// ```
768852
///
769-
/// Creating a `CStr` without a trailing nul byte is an error:
853+
/// Creating a `CStr` without a trailing nul terminator is an error:
770854
///
771855
/// ```
772856
/// use std::ffi::CStr;
@@ -869,7 +953,7 @@ impl CStr {
869953
/// requires a linear amount of work to be done) and then return the
870954
/// resulting slice of `u8` elements.
871955
///
872-
/// The returned slice will **not** contain the trailing nul that this C
956+
/// The returned slice will **not** contain the trailing nul terminator that this C
873957
/// string has.
874958
///
875959
/// > **Note**: This method is currently implemented as a 0-cost cast, but
@@ -894,7 +978,7 @@ impl CStr {
894978
/// Converts this C string to a byte slice containing the trailing 0 byte.
895979
///
896980
/// This function is the equivalent of [`to_bytes`] except that it will retain
897-
/// the trailing nul instead of chopping it off.
981+
/// the trailing nul terminator instead of chopping it off.
898982
///
899983
/// > **Note**: This method is currently implemented as a 0-cost cast, but
900984
/// > it is planned to alter its definition in the future to perform the

0 commit comments

Comments
 (0)