**未定义行为(Undefined Behavior, UB)**是指语言标准未定义程序行为的情况。编译器可以对程序做任意操作:程序可能崩溃、产生错误结果,甚至“正常工作”。UB通常源于数组越界、解引用空指针等错误。
int arr[5]; arr[10] = 42; // UB: 数组越界 int* p = nullptr; *p = 1; // UB: 解引用0
避免UB的方法是遵循标准,使用现代工具(ASan、UBSan、valgrind),尽量不使用裸指针,并编写安全代码。
如果UB发生在程序的一部分,这会影响到完全不同的“独立”代码部分吗?
会的!编译器在优化期间可能会进行意想不到的变换,特别是当发现存在UB时。
void foo(int* p) { if (p == nullptr) return; *p = 5; // 如果p不是nullptr,这就是UB!但是编译器可能会删除检查,认为p总是有效的。 }
故事
在一家大公司的服务器上,由于解引用空指针,时不时会发生随机的进程崩溃,难以重现:在debug模式下正常工作,而在release模式下却不行。
故事
在将代码从32位移植到64位时,混淆了数据类型,使用了int和指针之间的类型转换。在某些机器上运行正常,而在其他机器上出现崩溃和奇怪的伪影。
故事
在互联网上,有一个著名案例,无害的UB(数组越界)破坏了整个程序的工作:编译器删除了与数组操作相关的部分,甚至“优化”了与错误无关的代码部分。