C++ GCC`-fsanize=bounds`带有'std::array'的奇怪行为`
我尝试使用C++ GCC`-fsanize=bounds`带有'std::array'的奇怪行为`,c++,arrays,g++,C++,Arrays,G++,我尝试使用-fsanize=bounds选项查找代码中的越界问题,但我遇到了奇怪的行为: 例如,在以下代码中: #include <cstdlib> #include <array> int main (int, char **) { std::array <char, 1> a; const char b = a [X]; // X <--- put index here! return EXIT_SUCCESS; } #
-fsanize=bounds
选项查找代码中的越界问题,但我遇到了奇怪的行为:
例如,在以下代码中:
#include <cstdlib>
#include <array>
int main (int, char **)
{
std::array <char, 1> a;
const char b = a [X]; // X <--- put index here!
return EXIT_SUCCESS;
}
#包括
#包括
int main(int,char**)
{
std::数组a;
const char b=a[X];//X我无法立即找到这方面的文档(或者,实际上,任何类型的强文档),但我觉得这很可能是该功能的一个实现细节。获取一个超过结束指针的值是合法的,因此实现无法捕捉到这一点。实现似乎是通过查看指针来工作的,而不是等待这样的指针被取消引用(如果您考虑如何创建-fsanize=bounds
,这会有一定的意义)
简而言之,这可能只是该工具的一个限制
在GCC 6中,您可以尝试使用-fsanize=bounds strict
,这会增加工具的强度(包括添加对检测OOB对灵活的类成员数组的访问的支持)
我不知道这是库问题还是编译器问题,但无论如何,值得注意的是,同样的问题目前是针对clang()的一个开放bug,并且注释中的假设与我上面的漫谈相匹配
也意味着这最终是预期的行为。
-fsanize=边界
此选项启用数组边界检测。检测到各种越界访问。灵活的数组成员,灵活的
类似于数组成员的数组,以及具有静态
未检测存储
使用X>1会触发此检查(数组超出边界),这是由于“a”字符声明,大小为1
编辑
尽管如此,正如@Lightness Races in Orbit所说,这并不是一个答案,但为读者提供了一些信息
案例X==1是一个过去的端点这一事实让我想到了迭代器,在这里允许一个过去的端点
@GLUTTON证实,使用类C数组而不是std::array可以解决案例a[1]正如预期的那样,显示为错误。未定义的行为未定义。@AlgirdasPreidžius,我的问题是关于使用ubsan
工具,而不是关于语言。你到底为什么要使用N==1的std::array并引用超出范围的索引?@foxfireee,如果让你高兴的话,你可以使用N==1024*1024并尝试访问元素1024*1024在循环内部的某个地方。我要做一个评论:一个可能的解决方法是使用-D_GLIBCXX_DEBUG
诊断越界访问。MSVC在默认情况下在调试模式下也会这样做。这并不能真正回答问题,这就是为什么X==1
也不被视为违规(正如人们可能期望的那样)。解释了为什么结束后的一次不会触发错误。我认为a{X]被视为迭代器,至少对于这种检查而言。值得注意的是,同样的问题目前是针对clang的一个开放性错误
-我的问题有点不同,并且仅在std::array
(使用类似C的数组时,它工作得很好)。