char 和 char& 之间是否存在相对复制开销差异?

Is there a relative copy overhead difference between char and char&?

例如,

string str = "hello";
for (char  c : str) { } // 1 copy
for (char& c : str) { } // 2 reference

1和2之间是否存在相对复制开销差异? char 是 1 个字节。因此,在第一个 for 循环中,1 个字节从 str 复制到 c。在第二个循环中,它通过引用传递。这里引用传递就是复制指针地址(4字节)?我想知道它在内部是如何工作的。

C++ 标准对此不作任何保证。然而,几乎所有通用硬件上的现代编译器都应该将两个循环转换为完全相同的代码(假设启用了优化),因为复制 char 或访问对它的引用的语义在机器代码级别是无关紧要的。

以下三个主要编译器正是这样做的: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 将循环展开 8 倍,gcc 保持简单,MSVCgcc 具有完全相同的循环体,但有很多更多 bounds/stack 检查它周围的样板文件。

但是如果你关注循环体,每个编译器的两个函数(忽略标签和寄存器名称)的机器代码完全相同。


我个人不对内置数字类型使用 const 引用,因为我知道(在我使用 x86 的情况下)CPU 无论如何都会将它们保存在寄存器中并且复制它们没有开销.这不一定在每个硬件上都是正确的,但在那种情况下你需要自己调查 - 你的编译器可能比你更了解它。