循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次

In loop condition: why is strlen() called every time, but vector.size() gets called only once?

本文关键字:调用 vector size 一次 为什么 条件 strlen 循环      更新时间:2023-10-16

代码:

#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()只被调用一次

为什么?

参数是常量,并且它们在内部循环中没有更改参数。

您误解了生成的程序集。这并不是说假设向量的大小不变,只是对v.size()的调用是内联的。向量的大小仍然在每次循环迭代时重新计算,并加载到rax中。

const限定符只是阻止函数fg修改它们所引用的对象。这并不意味着它们可以假设对象是真正不可变的,并且不能改变大小。编译器必须假设非内联函数可能正在更改向量,其中包括printf。因此,函数必须重新计算向量的大小才能正确。

通过关闭内联(-fno-inline(,您可以进一步说服自己,即使进行了优化,也会重新计算大小。生成的程序集非常清楚地演示了对vector::size的调用。