c++ - 在循环条件 : why is strlen() called every time, 中,但 vector.size() 只被调用一次?

标签 c++ gcc assembly

<分区>

代码:

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

这是为什么?

参数是常量,在内循环中不改变参数。

最佳答案

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

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

您可以进一步说服自己重新计算大小,即使经过优化,turning off inlining (-fno-inline) .生成的程序集非常清楚地演示了对 vector::size 的调用。

关于c++ - 在循环条件 : why is strlen() called every time, 中,但 vector.size() 只被调用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53032376/

相关文章:

python - 如何加快编程的计算速度?

c++ - “输入”未命名类型错误。不知道为什么吗?

c - gdb 在 Centos 上找不到调试信息

c++ - 分析崩溃 - 将反汇编指令翻译成 C++ 等价物

c++ - 是否可以在标准弱指针之上实现非拥有 "slightly smart"指针?

c++ - boost 间隔矩阵

c++ - unique_ptr 没有操作删除

c++ - 无法将 boost 库与 CMake 链接

c - ELLCC 嵌入式 LLVM 编译失败,某些 asm 指令针对 Thumb2 Cortex-M0

assembly - ARM指令SWI和SVC完全相同吗?