#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的副本。
答案 0 :(得分:4)
该标准非常明确地规定,大多数形式的未定义行为是“无需诊断”。这意味着您的编译器没有诊断UB的义务(这也是不合理的,因为在很多情况下非常很难做到)。取而代之的是,允许编译器假设您“当然没有”编写任何UB并生成代码,就像您没有那样。而且,如果您做,那就在您身上,并且可以保留碎片。
某些工具(例如main.js
和asan
并将编译器的警告级别提高到11)将为您检测 some UB。但不是全部。
您的编译器实现者并不伤害您。他们会尽力警告您UB。因此,至少您应该启用所有警告并让它们尽可能地为您提供帮助。
检测UB的一种方法是对C ++标准有充分的了解,并非常认真地阅读代码。但是,您确实不能做得更好,+让一些工具来帮助您找到容易实现的目标。您只需有知道(所有)规则并知道您在做什么。
C ++中没有训练轮或类似工具。