From 6e4680950c847be939e620f9c2f745fbd3cabf72 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 30 Aug 2024 15:08:21 +0200 Subject: [PATCH] add note regarding unsafe blocks and place expressions --- personal/_posts/2024-08-14-places.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/personal/_posts/2024-08-14-places.md b/personal/_posts/2024-08-14-places.md index 813bfc9..4b93ee5 100644 --- a/personal/_posts/2024-08-14-places.md +++ b/personal/_posts/2024-08-14-places.md @@ -151,6 +151,17 @@ match *ptr { _val => "not happy" } // This is UB. The scrutinee of a `match` expression is a place expression, and if the pattern is `_` then a value is never constructed. However, when an actual binder is present, this introduces a local variable and a place-to-value coercion is inserted to compute the value that will be stored in that local variable. +**Note on `unsafe` blocks.** +Note that wrapping an expression in a block forces it to be a value expression. +This means that `unsafe { *ptr }` always loads from the pointer! +In other words: +```rust +let ptr = std::ptr::null::(); +let _ = *ptr; // This is fine! +let _ = unsafe { *ptr }; // This is UB. +``` +The fact that braces force a value expression can occasionally be useful, but the fact that `unsafe` blocks do that is definitely quite unfortunate. + ### Are there also value-to-place coercions? So far, we have discussed what happens when a place expression is encountered in a spot where a value expression was expected. -- 2.30.2