Typically, a piece of iron can take days, weeks, months, and sometimes even years to get that first coat of rust. It’s an extremely common reaction, since iron tends to react easily when it comes into contact with oxygen.
The intensity of rusting will be affected by the amount of exposure the piece of metal gets to water and oxygen. Jewelers and people who work with optical components often use a compound called rouge,” also known as “jeweler’s rouge” or “red rouge.” The compound contains a fine ferric oxide powder capable of giving different surfaces a shiny finish after a good polishing session.
Though not as potent and fast as other polishing products, rouge is still widely used by many jewelers and opticians; you can even use a specific type of rouge called a “stropping compound” on leather strops to help sharpen knives and razor blades better. Average rouge is sold as either paste, powder, polished or laced cloths, or a single solid bar.
Producing steel and iron alloys requires a lot of feedstocks, i.e. raw unfiltered material. For instance, 0.5% of iron(III) oxide makes up calamine lotion, which we use for itches and irritation.
In addition, the lotion gets its famous pinkish hue as a result of the reddish rust mixed with zinc oxide. Since our bodies already produce iron naturally, there are no real dangers to us adding a bit extra.
In other words, if your body accumulates iron too quickly, then it’s probably a good idea not to drink water that’s literally full of it. Tetanus is caused by the bacteria called Clostridium retain, found in animal feces, soil, and dust.
If you were to actually swallow a rusty nail or a large piece of metal with lots of rust on it, you might get a lower form of tetanus. People who weld, solder, or mine tend to inhale lots of rust dust, which in turn can lead to sclerosis.
However, the disease takes years to fully develop, and we can prevent contracting it by using proper protection like masks. After all, if we use rust in cosmetic and medical products regularly, there’s no real reason to fear if we swallow a bit of it.
Well, from what I’ve learned, there are quite a few households that have pots, pans, silverware, and cups that have some minor rust on them. Moreover, there are often images floating around online of what typical water pipes look like, and they are almost always rusty on the inside.
Therefore, enjoy your meals and don’t worry about ingesting some iron(III) oxide; it might even be good for you. All the code we’ve discussed so far has had Rust ’s memory safety guarantees enforced at compile time.
However, Rust has a second language hidden inside it that doesn’t enforce these memory safety guarantees: it’s called unsafest and works just like regular Rust, but gives us extra superpowers. In these cases, you can use unsafe code to tell the compiler, “Trust me, I know what I’m doing.” The downside is that you use it at your own risk: if you use unsafe code incorrectly, problems due to memory unsafely, such as null pointer referencing, can occur.
It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust ’s safety checks: if you use a reference in unsafe code, it will still be checked. The unsafe keyword only gives you access to these five features that are then not checked by the compiler for memory safety.
In addition, unsafe does not mean the code inside the block is necessarily dangerous or that it will definitely have memory safety problems: the intent is that as the programmer, you’ll ensure the code inside an unsafe block will access memory in a valid way. Keep unsafe blocks small; you’ll be thankful later when you investigate memory bugs.
Parts of the standard library are implemented as safe abstractions over unsafe code that has been audited. We’ll also look at some abstractions that provide a safe interface to unsafe code.
Unsafest has two new types called raw pointers that are similar to references. As with references, raw pointers can be immutable or mutable and are written as *coast T and *but T, respectively.
Listing 19-1 shows how to create an immutable and a mutable raw pointer from references. Listing 19-2 shows how to create a raw pointer to an arbitrary location in memory.
Note also that in Listing 19-1 and 19-3, we created *coast i32 and *but i32 raw pointers that both pointed to the same memory location, where sum is stored. By inserting the unsafe block around our call to dangerous, we’re asserting to Rust that we’ve read the function’s documentation, we understand how to use it properly, and we’ve verified that we’re fulfilling the contract of the function.
In fact, wrapping unsafe code in a safe function is a common abstraction. As an example, let’s study a function from the standard library, split_at_but, that requires some unsafe code and explore how we might implement it.
For simplicity, we’ll implement split_at_but as a function rather than a method and only for slices of i32 values rather than for a generic type T. Then it asserts that the index given as a parameter is within the slice by checking whether it’s less than or equal to the length.
In this case, because we have a mutable slice to i32 values, as_mut_PTR returns a raw pointer with the type *but i32, which we’ve stored in the variable PTR. We use this function to create a slice that starts from PTR and is mid items long.
We’ve created a safe abstraction to the unsafe code with an implementation of the function that uses unsafe code safely, because it creates only valid pointers from the data this function has access to. This code takes an arbitrary memory location and creates a slice 10,000 items long.
We don’t own the memory at this arbitrary location, and there is no guarantee that the slice this code creates contains valid i32 values. For this, Rust has a keyword, ex tern, that facilitates the creation and use of a Foreign Function Interface (FFI).
Listing 19-8 demonstrates how to set up an integration with the abs function from the C standard library. Functions declared within ex tern blocks are always unsafe to call from Rust code.
Listing 19-8: Declaring and calling an ex tern function defined in another language We can also use ex tern to create an interface that allows other languages to call Rust functions.
We also need to add a # annotation to tell the Rust compiler not to mangle the name of this function. Mangling is when a compiler changes the name we’ve given a function to a different name that contains more information for other parts of the compilation process to consume but is less human-readable.
If two threads are accessing the same mutable global variable, it can cause a data race. Listing 19-9 shows an example declaration and use of a static variable with a string slice as a value.
Static variables are similar to constants, which we discussed in the section in Chapter 3. Listing 19-10 shows how to declare, access, and modify a mutable static variable named COUNTER.
Listing 19-10: Reading from or writing to a mutable static variable is unsafe This code compiles and prints COUNTER: 3 as we would expect because it’s single threaded.
Having multiple threads access COUNTER would likely result in data races. Where possible, it’s preferable to use the concurrency techniques and thread-safe smart pointers we discussed in Chapter 16 so the compiler checks that data accessed from different threads is done safely.
By using unsafe imply, we’re promising that we’ll uphold the invariants that the compiler can’t verify. As an example, recall the Sync and Send marker traits we discussed in the section in Chapter 16: the compiler implements these traits automatically if our types are composed entirely of Send and Sync types.
A union is similar to a struct, but only one declared field is used in a particular instance at one time. Using unsafe to take one of the five actions (superpowers) just discussed isn’t wrong or even frowned upon.