For example,
string str = "hello";
for (char c : str) { } // 1 copy
for (char& c : str) { } // 2 reference
Is there a relative copy overhead difference between 1 and 2? char is 1 byte. Thus, in the first for loop, 1 byte is copied from str to c. In the second loop, it passed by reference. Here, to passed by reference is to copy the pointer address(4 bytes)? I wonder how it works internally.
The C++ standard does not guarantee anything about this. However, almost any modern compiler on common hardware should transform both loops into exactly the same code (assuming optimizations are enabled), because the semantics of copying the char or accessing a reference to it are irrelevant at the machine code level.
Here are three major compilers doing exactly that: https://godbolt.org/g/XfRX38
volatile char x;
void fooCopy(std::string str)
{
for (char c : str) {
x = c;
}
}
void fooReference(std::string str)
{
for (char& c : str) {
x = c;
}
}
clang
unrolls the loop by a factor of 8, gcc
keeps it simple, and MSVC
has exactly the same loop body as gcc
but with a lot more bounds/stack checking boilerplate around it.
But if you focus on the loop bodies, the machine code is exactly identical between the two functions (disregarding label and register names) for each compiler.
I personally don't use const references to inbuilt numeric types because I know (in my case of working on x86) that the CPU will keep them in a register anyway and that copying them has no overhead. That doesn't have to be true on every hardware, but in that case you need to investigate yourself - chances are your compiler knows it better than you though.