Official Rust material tries very hard to never talk about "zero cost" by itself, so you'll have to cite where you see "zero cost" without further qualification. The article states zero runtime cost, so the author of the post is aware of that. In most cases, "zero cost" is used in the context of zero-cost abstractions.
Your Stroustrup quote only partially and obliquely deals with zero-cost abstractions. A better explanation, emphasis mine:
It means paying no penalty for the abstraction, or said otherwise, it means that whether you use the abstraction or instead go for the "manual" implementation you end up having the same costs (same speed, same memory consumption, ...).
This means that any time you see "zero-cost abstraction", you have to have something to compare the abstraction against; only then can you tell if it's truly zero-cost.
I don't think that shadowing even counts as an abstraction, but let's pretend it does (and I'll word the rest of my answer as if I believe it is).
Shadowing a variable means having multiple distinct variables with the same name, with the later ones precluding access to the previous ones. The non-"abstract" version of that is having multiple distinct variables of different names. I'd say that having two variables of the same name is the same cost as having two variables of different names, so it is a zero-cost abstraction.
See also:
Playing the game further, you can ask "is having two variables a zero-cost abstraction?". I'd say that this depends on what the variables are and how they relate.
In this example, I'd say that this is a zero-cost abstraction as there's no more efficient way I could have written the code.
fn example() {
let a = String::new();
let a = a;
}
On the other hand, I'd say that this is not a zero-cost abstraction, as the first a
will not be deallocated until the end of the function:
fn example() {
let a = String::new();
let a = String::new();
}
A better way I could choose to write it would be to call drop
in the middle. There are good reasons that Rust doesn't do this, but it's not as efficient in regards to memory usage as a hand-written implementation could be.
See also: