循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
In loop condition: why is strlen() called every time, but vector.size() gets called only once?
代码:
#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
限定符只是阻止函数f
和g
修改它们所引用的对象。这并不意味着它们可以假设对象是真正不可变的,并且不能改变大小。编译器必须假设非内联函数可能正在更改向量,其中包括printf
。因此,函数必须重新计算向量的大小才能正确。
通过关闭内联(-fno-inline
(,您可以进一步说服自己,即使进行了优化,也会重新计算大小。生成的程序集非常清楚地演示了对vector::size
的调用。
相关文章:
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- 在 C++20 之前,在带有常量或引用字段的"A"上调用 'std::vector<A>
- 为什么我的向量::擦除调用会抛出"vector subscript out of range"?
- 错误:调用"es_queue::set_rpc_vector(std::vector >&, std::__cxx11::string)"没有匹配函数
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- C++如果调用 vector,矢量分割错误会导致崩溃
- 调用 vector.erase() 函数时指针操作无效错误
- 我是否应始终在功能末尾调用vector clear()
- 在调用vector::assign()之前调用vector::reserve()更好吗?
- 在向量引用上调用 vector::reserve()
- 对存储在boost::any中的向量调用vector::size()
- 从Cocos2d::Layer派生的类有一个指针数据成员.这个元素也有一个向量容器.调用vector::push_bac
- 错误C2280:试图引用已删除的函数(试图调用vector.erase)
- 在C++中,为什么我可以在<double>类中调用 vector::begin() 来获取私有内容?
- 调用vector.erase()时出现分段错误
- 调用vector中对象的成员函数