gpt4 book ai didi

c++ - C++ 编译器可以优化对 at() 的调用吗?

转载 作者:行者123 更新时间:2023-12-03 15:57:09 24 4
gpt4 key购买 nike

由于未检查通过 [] 运算符进行的常规数组访问,因此当您的程序存在远程代码执行漏洞或由于缓冲区溢出导致数据泄漏时,成为头条新闻并不有趣。

大多数标准数组容器包含 at()允许对数组元素进行边界检查访问的方法。这使得越界数组访问定义良好(抛出异常),而不是未定义的行为。

这基本上消除了缓冲区溢出任意代码执行漏洞,还有一个 clang-tidy check警告您应该使用 at()当索引为非常量时。所以我改变了很多地方。

大多数托管语言都有检查数组,它们的编译器可以在可能的情况下消除检查。

我知道 C++ 编译器可以做很棒的优化。问题是 C++ 编译器可以这样做以消除对 at() 的调用吗?当他们看到它不能溢出?

最佳答案

这是在托管语言中会受到边界检查消除的经典案例:迭代到大小。

#include <vector>

int test(std::vector<int> &v)
{
int sum = 0;
for (size_t i = 0; i < v.size(); i++)
sum += v.at(i);
return sum;
}

当索引和大小都是常量时(可以通过常量传播解决),这并不像优化那么简单,它需要对值之间的关系进行更高级的推理。

As seen on Godbolt 、GCC (9.2)、Clang (9.0.0) 甚至 MSVC (v19.22) 都可以合理处理此类代码。 GCC 和 Clang 自动矢量化。 MSVC 只生成一个基本循环:
$LL4@test:
add eax, DWORD PTR [r9+rdx*4]
inc rdx
cmp rdx, r8
jb SHORT $LL4@test

这还不错,但考虑到它 does vectorize使用 [] 的类似循环而不是 .at() ,我必须得出结论:是的,使用 at 的成本很高。即使在我们可能期望的一些基本情况下(特别是考虑到没有范围检查,因此自动矢量化步骤似乎没有理由害怕)。如果您选择仅针对 GCC 和 Clang,那么问题就不大了。在更棘手的情况下,GCC 和 Clang 也可能“完全混淆”,例如当 passing the indexes through a data structure 时(不太可能是代码,但重点是,范围信息有时可能会丢失)。

关于c++ - C++ 编译器可以优化对 at() 的调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58233822/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com