@@ -310,13 +310,41 @@ pub fn spin_loop() {
310310/// behavior in the calling code. This property makes `black_box` useful for writing code in which
311311/// certain optimizations are not desired, such as benchmarks.
312312///
313+ /// In practice, `black_box` serves two purposes:
314+ ///
315+ /// 1. It forces the input to be calculated, even if its results are never used
316+ /// 2. It prevents the compiler from making optimizations related to the value of the returned
317+ /// type
318+ ///
319+ /// Note that `black_box` does not prevent its inputs from being optimized before they are passed
320+ /// to the function, though.
321+ ///
322+ /// ```
323+ /// // This...
324+ /// let y = black_box(5 * 10);
325+ /// // ...will still be optimized to this:
326+ /// let y = black_box(50);
327+ /// ```
328+ ///
329+ /// In the above example, `5 * 10` is replaced with `50` by the compiler. You can prevent this by
330+ /// moving the multiplication outside of `black_box`:
331+ ///
332+ /// ```
333+ /// // No assumptions can be made about either number, so the multiplication is kept.
334+ /// let y = black_box(5) * black_box(10);
335+ /// ```
336+ ///
337+ /// <div class="warning">
338+ ///
313339/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
314340/// extent to which it can block optimisations may vary depending upon the platform and code-gen
315341/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the
316342/// identity function. As such, it **must not be relied upon to control critical program behavior.**
317343/// This also means that this function does not offer any guarantees for cryptographic or security
318344/// purposes.
319345///
346+ /// </div>
347+ ///
320348/// [`std::convert::identity`]: crate::convert::identity
321349///
322350/// # When is this useful?
@@ -357,7 +385,7 @@ pub fn spin_loop() {
357385/// ```
358386/// use std::hint::black_box;
359387///
360- /// // Same `contains` function
388+ /// // Same `contains` function.
361389/// fn contains(haystack: &[&str], needle: &str) -> bool {
362390/// haystack.iter().any(|x| x == &needle)
363391/// }
@@ -366,8 +394,13 @@ pub fn spin_loop() {
366394/// let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
367395/// let needle = "ghi";
368396/// for _ in 0..10 {
369- /// // Adjust our benchmark loop contents
370- /// black_box(contains(black_box(&haystack), black_box(needle)));
397+ /// // Force the compiler to run `contains`, even though it is a pure function whose
398+ /// // results are unused.
399+ /// black_box(contains(
400+ /// // Prevent the compiler from making assumptions about the input.
401+ /// black_box(&haystack),
402+ /// black_box(needle),
403+ /// ));
371404/// }
372405/// }
373406/// ```
0 commit comments