代码:
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
void f(const char* s) {
for (size_t i = 0; i < strlen(s); i++) {
printf("%c ", s[i]);
}
}
void g(const vector<int>& v) {
for (size_t i = 0; i < v.size(); i++) {
printf("%d ", v[i]);
}
}
编译链接:https://godbolt.org/z/PCi5yg
您将看到汇编代码:
f()
中,每次strlen(s)
都会被调用; g()
中,v.size()
仅被调用一次。那是为什么?
参数是const,它们在内部循环中没有更改参数。
答案 0 :(得分:8)
您误解了生成的程序集。并不是假定矢量的大小保持不变,而是内联了对v.size()
的调用。向量的大小仍会在每次循环迭代时重新计算,并加载到rax
中。
const
限定符仅阻止函数f
和g
修改它们引用的对象。这并不意味着他们可以假定对象是真正不变的,并且不能更改大小。编译器必须假定非内联函数可能正在更改矢量,并且其中包括printf
。因此该函数必须重新计算向量的大小才能正确。
您可以进一步说服自己,turning off inlining (-fno-inline
)甚至重新优化了大小。生成的程序集非常清楚地演示了对vector::size
的调用。