未检测到超出范围的指针算术?

时间:2019-04-25 18:02:45

标签: c++ undefined-behavior

根据Wikipediathis,此代码是未定义的行为:

#include <iostream>
int main(int, char**) {
    int data[1] = {123};
    int* p = data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;
}

clang++-6.0 -fsanitize=undefined编译并执行后,检测到未定义的行为,这很了不起,我得到以下消息:

ub.cpp:5:19: runtime error: index 5 out of bounds for type 'int [1]'

但是当我不使用数组时,无法检测到未定义的行为:

#include <iostream>
int main(int, char**) {
    int data = 123;
    int* p = &data + 5; // undefined behavior
    std::cout << *(p - 5) << std::endl;
}

即使这是 still 不确定的行为,消毒剂也不会检测到任何东西。 Valgrind也没有任何问题。有什么办法可以检测到这种未定义的行为?

由于我从不访问任何无效数据,因此这不是Recommended way to track down array out-of-bound access/write in C program的副本。

1 个答案:

答案 0 :(得分:4)

该标准非常明确地规定,大多数形式的未定义行为是“无需诊断”。这意味着您的编译器没有诊断UB的义务(这也是不合理的,因为在很多情况下非常很难做到)。取而代之的是,允许编译器假设您“当然没有”编写任何UB并生成代码,就像您没有那样。而且,如果您,那就在您身上,并且可以保留碎片。

某些工具(例如main.jsasan并将编译器的警告级别提高到11)将为您检测 some UB。但不是全部。

您的编译器实现者并不伤害您。他们会尽力警告您UB。因此,至少您应该启用所有警告并让它们尽可能地为您提供帮助。

检测UB的一种方法是对C ++标准有充分的了解,并非常认真地阅读代码。但是,您确实不能做得更好,+让一些工具来帮助您找到容易实现的目标。您只需知道(所有)规则并知道您在做什么。

C ++中没有训练轮或类似工具。