In C++ you can write code like this:
#include <string>
#include <iostream>
void print(const std::string &s) {
std::cout << s << std::endl;
}
int main() {
print("Hello world!");
}
This compiles with no warnings, and at no point in the function "main" do you see that you're causing a memory allocation and a copy by implicitly converting your static message to a std::string, passing it to the function, and deallocating it. If you code-review "main", it doesn't look like you're doing an allocation because you're passing a const char *; if you code-review "print", it doesn't look like you're doing an allocation because you're accepting a std::string, which has already been allocated. So you get an extra, unneeded allocation in the chasm between the two, and it's very hard to track down the performance problem (or, in the worst case, a hang - memory allocation can block on flushing buffers or swapping things out, so you'd better not run into this situation in code that could itself be involved in writing to disk!).Compare the equivalent Rust code:
fn print(s: &String) {
println!("{}", s);
}
fn main() {
print("Hello world!");
}
which produces a "mismatched types" error: "expected reference `&String`, found reference `&'static str`."To get this to compile, you have to write something like print(&"Hello world!".to_owned()); , where you specifically instruct an allocation to happen.
The objection is to implicit allocations. Explicit allocations are fine.