-O0编译时std::vector<T>::operator[]的二进制代码位置问询
关于std::vector::operator[]在-O0编译下的二进制位置与执行流程
首先看问题中的代码:
#include <vector> int foo() { std::vector<int> const v{17,2,3}; return v[0] + v[2]; }
1. _ZNKSt6vectorIiSaIiEEixEm的二进制代码位置
这个经过名字修饰的函数是const std::vector<int>::operator[],它的二进制代码位于C++标准库的预编译库文件中:
- 在Linux系统下,通常是动态链接库
libstdc++.so,或者静态链接库libstdc++.a; - 在Windows系统下,对应MSVC的动态链接库
msvcp140.dll(或同系列版本),或者静态链接库libcmt.lib等。
标准库的实现由编译器厂商提供,不会出现在你自己编写的代码生成的汇编里,除非你手动编译并链接了自定义版本的标准库源码。
2. 链接后程序执行v[0]和v[2]取值的流程
当该翻译单元与调用foo()的其他单元完成链接后,程序运行时的执行步骤如下:
- 进入
foo()函数后,先在栈上构造std::vector<int> const v:完成内存分配、元素初始化(将17、2、3写入对应内存),并设置vector内部的三个核心成员:指向数据起始位置的指针、当前元素数量(size)、已分配内存的容量(capacity)。 - 每次调用
const std::vector<int>::operator[]时:- 由于是-O0编译(debug模式),函数通常会先执行边界检查:对比传入的索引和vector的size,若索引越界会触发断言(比如GCC的
__glibcxx_check_bound); - 计算目标元素的内存地址:用vector内部的起始数据指针,加上
索引 * sizeof(int)(这里int占4字节,索引0对应起始地址,索引2对应起始地址+8字节);
- 由于是-O0编译(debug模式),函数通常会先执行边界检查:对比传入的索引和vector的size,若索引越界会触发断言(比如GCC的
- 取出两个地址对应的int值(17和3),相加后返回结果20。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

